New to Python and having done some reading, I'm making some methods in my custom class class methods rather than instance methods.
So I tested my code but I hadn't changed some of the method calls to call the method in the class rather than the instance, but they still worked:
class myClass:
@classmethod:
def foo(cls):
print 'Class method foo called with %s.'%(cls)
def bar(self):
print 'Instance method bar called with %s.'%(self)
myClass.foo()
thing = myClass()
thing.foo()
thing.bar()
This produces:
class method foo called with __main__.myClass.
class method foo called with __main__.myClass.
instance method bar called with <__main__.myClass instance at 0x389ba4>.
So what I'm wondering is why I can call a class method (foo) on an instance (thing.foo), (although it's the class that gets passed to the method)? It kind of makes sense, as 'thing' is a 'myClass', but I was expecting Python to give an error saying something along the lines of 'foo is a class method and can't be called on an instance'.
Is this just an expected consequence of inheritance with the 'thing' object inheriting the foo method from its superclass?
If I try to call the instance method via the class:
myClass.bar()
then I get:
TypeError: unbound method bar() must be called with myClass instance...
which makes perfect sense.
thing.foo
is not a method call, it is an attribute access, It is basically the same thing asgetattr(thing, "foo")
. – Cholulathing.foo()
is calling thefoo
method of the objectthing
? Isn't an attribute Python's terminology for what other languages refer to as a variable or property? – Negress(thing.foo)()
is calling thefoo
method of the objectthing
" (parentheses for clarity) is a metaphor for "(thing.foo)()
is calling the callable objectthing.foo
", that is it. AFAIU, this object is created dynamically whengetattr(thing, "foo")
is called, and of course it has a reference tothing
object. – Cholulabar
, you can writething.foo = bar
, and then call itthing.foo()
ifbar
was callable. In this case the object returned bything.foo
is actually stored in the dictionarything.__dict__
, and not generated dynamically, as, i suppose, is the case with "instance methods" defined as a part of class definition. – Cholulaclass
statement defines two functions: one is bound to the class attributebar
, the other is wrapped in an instance ofclassmethod
and bound to the class attributefoo
.thing.foo
, then, is an attribute lookup whose result is a callable object, not the original function or theclassmethod
instance itself but an instance of themethod
class, produced by the descriptor protocol. – Mycosis