Reputation: 89
class A:
def __init__(self, text):
self.printStats()
A.printStats(text)
def printStats(self):
print(self)
a = A("Hello")
This prints:
<A object at 0x7f47e2f08ac8>
Hello
Why is this (A.printStats(text)
) possible? I understand what is happening (self
references text
), but I don't understand why.
Upvotes: 5
Views: 1773
Reputation: 78564
Your code would fail in Python 2 as calling a method via the class requires that the first argument of the class is actually an instance of the class.
In Python 3, the implementation is less stricter as the first argument is only expected to implement the required interface pertaining to an instance of the class; no check on whether the parameter is an instance is performed. And since you're not actually accessing any instance method/variable inside printStats
via self
this works and it simply prints the passed string 'hello'
.
Upvotes: 1
Reputation: 5939
When you create an instance of the class:
a = A('some text')
The self
argument becomes permanently bound to a
, this is the magic behind classes. If you try a.printStats('something')
this will raise an error as self
argument is already occupied by a
. You can recover the original function that has unbound self with a.printFunction.__func__
. Try a.printFunction.__func__('this will be self argument')
However, when you don't create an instance there is nothing to bind self
to so self
is still available for use. In such case you can treat A
as a simple dictionary holding functions.
A = {'__init__': someInitFunction,
'printStats': printStatsFunction}
You have to remember that the name self
is arbitrary and you can use any word instead, even not_self
.
Upvotes: 1
Reputation: 10667
A.printStats(text)
does NOT call printStats
with an instance of A
. It calls it with a string - no self
is passed.
def printStats(self):
# <--- here, "self" if the string "Hello", not an instance of A.
print(self)
A.printStats(self)
is equivalent to self.printStats
. Likewise if you have a function printStatsWithPrefix
;
class A:
def printStatsWithPrefix(self, prefix):
... # function body goes here
you'd have to do A.printStatsWithPrefix(self, prefix)
.
A note on style: By Python convention (PEP 8), you should use lowercase_with_underscores
for function names.
Upvotes: 5