noob question: "TypeError" wrong number of args

bruno at modulix onurb at xiludom.gro
Tue May 2 14:38:39 EDT 2006


Edward Elliott wrote:
> bruno at modulix wrote:
> 
>>>that 1) b is an object not a module*, and 2) objects pass references to
>>>themselves as the first argument to their methods.
>>
>>Nope. It's the MethodType object (a descriptor) that wraps the function
>>that do the job. The object itself is totally unaware of this.
> 
> 
> It's shorthand, not to be taken literally.
> 

It is to be taken literally. Either you talk about how Python
effectively works or the whole discussion is useless.

> 
>>>Making people pass 'self'
>>
>>s/self/the instance/
>>
>>
>>>explicitly is stupid
>>
>>No. It's actually a feature.
>  
> potato, potahto.  
> 

tss...

> 
>>>the first argument, leading to these kinds of mistakes.  The compiler
>>>should handle it for you
>
>>
>>I don't think this would be possible if we want to keep the full
>>dynamism of Python. How then could the compiler handle the following code
>>?
>>
>>class MyObj(object):
>>  def __init__(self, name):
>>    self.name = name
> 
> 
> class MyObj(object):
>   def __init__(name):
>     self.name = name

You skipped the interesting part, so I repost it and ask again: how
could the following code work without the instance being an explicit
parameter of the function to be used as a method ?

def someFunc(obj):
  try:
    print obj.name
  except AttributeError:
    print "obj %s has no name" % obj

import types
m = MyObj('parrot')
m.someMeth = types.MethodType(someFunc, obj, obj.__class__)
m.someMeth()

You see, wrapping a function into a method is not done at compile-time,
but at runtime. And it can be done manually outside a class statement.
In the above example, someFunc() can be used as a plain function.

In fact, almost any existing function taking at least one argument can
be turned into a method (in theory at least - practically, you of course
need to make sure the first argument is of a compatible type). This
wouldn't work with some automagical injection of the instance in the
function's local namespace, because you would then have to write
"method"'s code diffently from function's code.

> And the rest should work fine.  When the interpreter sees a method
> declaration,

The interpreter never sees a 'method declaration', since there is no
such thing as a 'method declaration' in Python. The def statement
creates a *function* object:

>>> class Parrot(object):
...     def test(self):
...             pass
...     print "type(test) is : ", type(test)
...
type(test) is :  <type 'function'>

>>>but in practice you don't declare
>>>self as a parameter to module functions
>>
>>def someOtherFunc():
>>  print "hello there"
>>
>>m.someFunc = someOtherFunc
>>m.someFunc()
>  
> Complete non-sequitor, what does this have to do with self?  

It has to do that the obj.name() syntax doesn't imply a *method* call -
it can as well be a plain function call. Also, and FWIW:
>>> def moduleFunc():
...     print self.name
...
>>> moduleFunc()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in moduleFunc
NameError: global name 'self' is not defined
>>>



HTH
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list