To refer to the instance in which the method is being called
all the question
How is “self” typically used in a Python method within a class?
To set the residual value in an expression where the method is used
To refer to the instance in which the method is being called
To terminate a loop
The number of parameters to the method
Ah I see.
The wording means, if you had a class, and defined a method within it, does self refer to the method call in that instance.
For example:
class Dog(object):
def __init__(self, legs):
self.legs = legs
def bark(self):
print("Woof!")
rex = Dog(4)
rex.bark()
The bark method uses self…why?
To refer to the instance in which the method is being called
if I want to say in my words I’ll say → self go to the class Dog and search about bark() method
I found it helpful when I initially struggled with self to swap the word mentally with this instance of the class
So I would say, call the bark method on this instance of the dog class.
So if you had a lot of dog instances, like Rover, Lassie and Fido, as well as Rex, then you know which instance of dog you are calling bark() on.
Imagine you had a function that made dicts to represent dogs:
def createDog(name):
return {"name": name}
You would use it like this:
fido = createDog("fido")
Now you can have a bark function if you want like this:
bark(fido)
But, you want bark to be a command to fido, so you want to do something like this:
fido["bark"]()
Alright, change up createDog then:
def createDog(name):
def bark():
print("BARK")
return {"name": name, "bark": bark}
When I run this it works!:
>>> def createDog(name):
... def bark():
... print("BARK")
... return {"name": name, "bark": bark}
...
>>> x = createDog("fido")
>>> x["bark"]()
BARK
>>>
There’s a problem though, what if I want fido to say his name when he barks. Well…how does the bark() function get to the “name” of the dict?
I’ll stop there and present this to you as a puzzle:
How do you change createDog to let fido bark his name?
print it like this
print(x[‘name’]) this print the name
Or :::
add print(name)
but why you call bark() like this!
Yes! That’s one way to do it. But, you could also do this:
def createDog(name):
myself = {"name": name}
def bark():
print("BARK", myself["name"])
myself["bark"] = bark
return myself
And that is what self is. It’s just a reference back to the dict that holds all the things like name so that you can access it inside a function.
The reason I’m doing this:
fido["bark"]()
Is that’s exactly what happens when you do this:
fido.bark()
Make a real Dog class, and then do this:
print(Dog.__dict__)
Or this:
print(Dog.__dict__["bark"])
Then this:
Dog.__dict__["bark"]()
Check it out:
>>> class Dog:
... def bark():
... print("BARK")
>>> Dog.__dict__
mappingproxy({'__module__': '__main__', 'bark': <function Dog.bark at 0x107905950>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None})
>>> Dog.__dict__["bark"]
<function Dog.bark at 0x107905950>
>>> Dog.__dict__["bark"]()
BARK
That “mapping” proxy is a Python3 wrapper around dicts, but essentially all a class boils down to is a dict with the functions and data in it. The class dict has the functions, and the objects will have the data.
Play with this. If you can sort out my alternative then you can understand what self is. It’s just a reference to that dict.
That a fantastic breakdown. Thanks Zed. I keep forgetting it’s all just dictionaries!