David Isaac wrote: > When I create an instance of a class, > are the class's functions *copied* to create the methods?
No, unless you explicitely do it. > Or are method calls actually calls of the class's functions? Depends on how the method was associated to the instance (you can set methods on a per-instance property), but in the general case (functions defined in the class body), yes. > I am sure this is both obvious I once had the same question when I was learning computers and programming. > and FAQ, Not AFAIK. > but I did not find a clear answer > (e.g. here > http://docs.python.org/tut/node11.html#SECTION0011340000000000000000 , > a lot turns on the meaning of 'equivalent'.) """ If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object. When the method object is called with an argument list, it is unpacked again, a new argument list is constructed from the instance object and the original argument list, and the function object is called with this new argument list. """ IOW, a method object is a callable object keeping references to both the instance and the function (note the "(pointers to) ... the function object"). You could represent yourself the method as something like: class Method(object): def __init__(self, im_func, im_self): self.im_self = obj self.im_func = func def __call__(self, *args, **kw): return self.im_func(self.im_self, *args, **kw) Now suppose that the 'function' type definition (yes, Python functions are objects) looks a bit like this: class function(object): . . . def __get__(self, obj): return Method(self, obj) And that looking up an attribute on an instance looks like this (dumbed down of course): def __getattribute__(self, name): if name in self.__dict__: return self.__dict__[name] elif hasattr(self.__class__, name) attrib = getattr(self.__class__, name) if hasattr(attrib, '__get__'): return attrib.__get__(self) else: return attrib else: raise AttributeError("object %s has no attribute %s" % (self, name) Then for : class Foo(object): def bar(self, val): return "%s %s" % (self, val) foo = Foo() Looking up 'bar' on 'foo': bar = foo.bar would resolve, thru __getattribute__ etc, to: bar = Method(Foo.bar, foo) Which, if then called, would resolve to Foo.bar(foo, 42) NB : reading the doc about new-style classes and the descriptor protocol may help: http://www.python.org/download/releases/2.2.3/descrintro/ http://users.rcn.com/python/download/Descriptor.htm HTH -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list