What happen if "self" in second argument

Started by
9 comments, last by Hraefn 9 years, 6 months ago

Hi i tried to read this code but i don't really understand what "self" being in second argument.Here is the example:






class Player(pygame.sprite.Sprite): 
    def update(self, dt, game): 
        game.tilemap.set_focus(new.x, new.y) 

class Game(object): 
    def initArea(self, mapFile): 
        self.tilemap = tmx.load(mapFile, screen.get_size()) 
        self.sprites = tmx.SpriteLayer() 
        self.tilemap.layers.append(self.sprites) 

def main(self):
    while 1: 
        self.tilemap.update(dt / 1000., self)

if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("Pyllet Town")
    Game(screen).main()

I already tried to ask others they said game is being an instance of Game(),but i really don't get it can you explain me a bit detailed?Thank you very much biggrin.png any help will be very appreciated

P.S:i cut some line but i hope you could still understand this code smile.png

Advertisement

Hello there.

Quick question: are you familiar with OOP?

'self.' is just a pythonic way of saying member of a class, or more like an instance of a class

Really quick comparison:


class jedi
{
public:
    int force;
    double lightsaber;
};

class jedi(object):
    def __init__(self):
        self.force = 0
        self.lightsaber = 0

In both cases force and lightsaber are class members, each instance of jedi will have their own force and lightsaber.

edit:

and python is designed that you need to pass 'self' (class instance) to its method among other arguments.

The self is a mechanism for accessing the Instance of the Class, that is executing the function.

Objects in Python are basically dictionaries, consisting of name:value pairs. To change the value of such a pair you need to explicitly say which object is to be affected (you only want one tileset to change or one player to move). In order for python to know which object you refer to, you use self: Whenever you call a function on an object the first argument passed to this function is a reference to the object executing the function. Python adds this reference silently (you don't need to explicitly pass it on call but you need it in the definition of your function).

Other languages resolve everything on a local scope first and then go up to the global scopes.

Basically it is all about scope resolution (something that comes up quite often), which is something like connecting you when you call someone. In that case you need to dial the prefix if you want to call someone in a different area. The thing with python is: you even need to dial that prefix for stuff in the same area, but python is nice and hands you the prefix.

Hello there.

Quick question: are you familiar with OOP?

'self.' is just a pythonic way of saying member of a class, or more like an instance of a class

Really quick comparison:














class jedi
{
public:
    int force;
    double lightsaber;
};













class jedi(object):
    def __init__(self):
        self.force = 0
        self.lightsaber = 0

In both cases force and lightsaber are class members, each instance of jedi will have their own force and lightsaber.

edit:

and python is designed that you need to pass 'self' (class instance) to its method among other arguments.

Yeah,i am pretty familiar with OOP smile.png ,i know what self do in first argument but not in the second argument,thank you

In order for python to know which object you refer to, you use self

What you mean is self referring to the object Game(screen).main().I'm pretty confused with self in second argument ^^a

Yeah,i am pretty familiar with OOP smile.png ,i know what self do in first argument but not in the second argument,thank you

Oh sorry, your first post was hard to understand.


self.tilemap.update(dt / 1000., self)

tilemap.update() takes 3 arguments, self(i.e tilemap), dt, and game. Second self indicates to 'game' instance, which tilemap is a member of. And since we're in scope of game class. we pass it as 'self'.

you beat me to the post.

@Kurai: this is the correct solution, next time you could specifically point out the line you are having trouble with (I only now saw it)

Yeah,i am pretty familiar with OOP smile.png ,i know what self do in first argument but not in the second argument,thank you

Oh sorry, your first post was hard to understand.






self.tilemap.update(dt / 1000., self)

tilemap.update() takes 3 arguments, self(i.e tilemap), dt, and game. Second self indicates to 'game' instance, which tilemap is a member of. And since we're in scope of game class. we pass it as 'self'.

Sorry for my post ^^a.Now i don't understand how game can be an instance mellow.png .Thank you

P.S: i only know how to make instance like this: a=classname() ^^a.

you beat me to the post.

@Kurai: this is the correct solution, next time you could specifically point out the line you are having trouble with (I only now saw it)

i'm really Sorry for my post ^^a

nothing to be sorry about, just constructive criticism.

Yeah,i am pretty familiar with OOP smile.png ,i know what self do in first argument but not in the second argument,thank you

Oh sorry, your first post was hard to understand.






self.tilemap.update(dt / 1000., self)

tilemap.update() takes 3 arguments, self(i.e tilemap), dt, and game. Second self indicates to 'game' instance, which tilemap is a member of. And since we're in scope of game class. we pass it as 'self'.

Sorry for my post ^^a.Now i don't understand how game can be an instance mellow.png .Thank you

P.S: i only know how to make instance like this: a=classname() ^^a.

Let us walk through this code:

First off is


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("Pyllet Town")
    Game(screen).main()

I think everything is quite straightforward except for the last line:

With Game(screen) you create an instance, but then it gets funny, because on that red hot instance a function is called (with .main()). Notice, that we do not take a reference to this new instance (we have no assignment). That means that the instance will be unreachable as soon as the function returns, but since the whole game runs in the main() method we are comfortable with that.

So now we look at the main() method:


def main(self):
    while 1: 
        self.tilemap.update(dt / 1000., self)

This is where things begin to get python and your confusion probably stems from:

From the Signature ( main(self) ) we can see, that we get passed one argument, the reference to the instance which this function is called on. This instance is of course the instance created with Game(screen). The tricky part is, that python passes this argument implicitly for every member method, which is why you don't see it in the call ( .main() ).

The next line is just the obvious main loop almost all games run in.

But then we get another strange line, which is easiest to understand when dissected:

self still is a reference to the instance of Game, so we are looking up it's tilemap (a reference to a tilemap instance) and call the function update on that tilemap instance.

This tilemap takes two arguments: The time that has passed since the last frame as well as the Game instance currently running the main funcion (probably to do some draw calls on that game object).

The update method itself will look like this:


def update(self, time_elapsed, game):
    #do something

What is important to understand is, that the self of the update function is a reference to the tilemap instance while the game in the update function is a reference to the game instance (we just handed this reference over by putting the self reference of the main function into this argument position).

I hope this helps, scoping and lifetimes can be quite confusing.

This topic is closed to new replies.

Advertisement