methods and functions, instances and classes
Bruno Desthuilliers
onurb at xiludom.gro
Mon Sep 4 13:07:36 EDT 2006
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 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list