noob question: "TypeError" wrong number of args

bruno at modulix onurb at xiludom.gro
Tue May 2 13:36:06 CEST 2006


Edward Elliott wrote:
> Holger wrote:
> 
>>oops, that was kinda embarrassing.
> 
> 
> It's really not.  You got a completely unhelpful error message saying you
> passed 2 args when you only passed one explicitly.  The fact the b is also
> an argument to b.addfile(f) is totally nonobvious until you know 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.

>  The syntax "b." is completely
> different from the syntax of any other type of parameter.
>
> The mismatch between the number of parameters declared in the method
> signature and the number of arguments actually passed

There's no mismatch at this level. The arguments passed to the *function
*object wrapped by the method actually matches the *function* signature.

> is nonobvious,
> unintuitive, and would trip up anybody who didn't already know what was
> going on.  It's ugly and confusing.  It's definitely a wart on the
> langauge.

I do agree that the error message is really unhelpful for newbies (now I
don't know how difficult/costly it would be to correct this).

> Making people pass 'self'

s/self/the instance/

> explicitly is stupid

No. It's actually a feature.


> because it always has to be
> 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

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()

> - and no, explicit is not *always* better than
> implicit, just often and perhaps usually.  While it's easy to recognize
> once you know what's going on, that doesn't make it any less of a wart.
> 
> * technically modules may be objects also,

s/may be/are/

> but in practice you don't declare
> self as a parameter to module functions

def someOtherFunc():
  print "hello there"

m.someFunc = someOtherFunc
m.someFunc()


-- 
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