Reputation: 583
In Python, if I define a simple class as follows:
>>> class myClass:
... z = zip('abc', (97, 98, 99))
... def meth(self):
... print(self)
...
>>>
and then enter the following at the prompt:
>>> myClass.meth
<function myClass.meth at 0x00639540>
>>> myClass.z
<zip object at 0x006432B0>
>>>
I find that the function object is presented by Python as belonging to the class (myClass.meth), but the attribute's string representation is not (its name is not preceded by myClass.) and is no different than if it were defined outside the class. What's the reasoning for this?
Upvotes: 2
Views: 763
Reputation: 531175
This appears to be a side effect of defining a function inside a class
statement. Defining the method at the global scope and calling type
explicitly doesn't add the class name to the function's name.
Consider the following code:
class myClass:
def meth(self):
print(self)
print("meth:", repr(meth))
x = lambda self: print(self)
print("x:", repr(x))
def mymeth(self):
print(self)
print("mymeth:", repr(mymeth))
C = type('C', (object,), {'mymeth': mymeth})
print("mymeth:", repr(C.mymeth))
whose output is
meth: <function myClass.meth at 0x1055c6b90>
x: <function myClass.<lambda> at 0x1055c6dd0>
mymeth: <function mymeth at 0x1055c6b00>
mymeth: <function mymeth at 0x1055c6b00>
Things to note:
Inside the class statement, the class name is added to the function name, whether you use def
or a lambda expression. This indicates that the behavior is not part of the def
statement. Also, this output is produced before the class
object itself is actually created.
Outside the class statement, the call to type
does not add the class name to the function name. This suggests that it's the class
statement itself, not the act of creating a class, that modifies the function name.
As to why this is the case? Presumably, it was decided that it would be useful to add a "fully qualified" method name in the output of function.__repr__
for debugging purposes, but I'm just speculating.
Upvotes: 2
Reputation: 11
It's because by calling myclass.meth
, you are simply pointing to the memory location where the function is located.
But for myClass.z
, you are just calling the contents returned by z
.
Similar to if it were:
class myClass:
x = 2
z = zip('abc', (97, 98, 99))
...
Then myClass.x
would be 2
SIDENOTE: In your code snippet, z
is a part of myClass
. For simplicity's sake, it is the same as if you'd define self.z = zip('abc', (97, 98, 99))
with in the constructor.
To get a clear understanding of why if really not like doing that, I'd check
Class vs Instance attributes
ADDED EXAMPLE:
Adding another example that might shine some light on the issue, consider this
def some_fn():
return 'hello world'
class A(object):
p = some_fn
Then
A.p
>> <function some_fn at 0x7f00fefbef80>
and NOT
>>> <function A.some_fn at ... >
Upvotes: 0
Reputation: 50819
z
is just a name, the value it holds is the builtin zip
class, which is not part of myClass
.
Upvotes: 0