On Class namespaces, calling methods

Laszlo Nagy gandalf at shopzeus.com
Sat Apr 10 11:28:31 EDT 2010


> class Uno:
>     a=1
>     def m():
>         print "mouse"
>
> Say that I have this "silly" class.
>
> While I can then write
>
>       print Uno.a
>
> I cannot write
>       Uno.m()
>
> I get the following error message:
>
>      TypeError: m() takes no arguments (1 given)
>   
As a workaround, use this pattern:

 >>> class Uno(object):
...     @classmethod
...     def m(cls):
...             print "mouse"
...
 >>> Uno.m()
mouse

> Since I have not created any instances of Uno, there is no self
> object, and I do not understand what object is supplied to the
> function call.
>   
The method is not actually called, so nothing is supplied. The error is 
raised when it turns out that the number of actual parameters and the 
number of formal parameters are different.

This is how you call a method:

#1. you try to call Uno.m() - the 'm' method object is found and taken
#2. argument values are evaluated and taken (in your example, there are 
no arguments)
#3. an extra argument is inserted in front of the argument list. This 
parameter is the object you where calling the method on. In this case, 
it is the 'Uno' class.
#4. actual arguments are assigned to formal parameters. If this fails 
for some reason, an exception is raised. In your case - the number of 
actual parameters is one, the number of formal parameters is zero. This 
is why you get an exception.
#5. If actual and formal parameters are matched, then the implicit self 
parameter is checked. If you call a method, then it must be an instance 
of the class being called (or an instanc of its subclass). For 
classmethods, it must be the same class (or a subclass of it).
#6. Function body executed, value returned

The implicit parameter (the instance, or for classmethods, the class) is 
ALWAYS added. So if you change your code:

class Uno:
    def m(self):
        pass

Then you won't get an exception in #4. But you will in #5, because 
instance methods must be called on an instance, not on a class. You can 
create a classmethod (e.g. with the @classmethod decorator) as shown 
above, and it will work.

> Could anybody explain what argument is being supplied to the method?
> Is ther any workaround to call the m function?
>
> Thank you
>   




More information about the Python-list mailing list