Help! Classes and function arguments

Alex Martelli alex at magenta.com
Tue Aug 22 03:18:04 EDT 2000


"Adam Clark" <bjrubble at shell16.ba.best.com> wrote in message
news:8nsnl0$2d57$1 at nntp1.ba.best.com...
> Hi, I'm having this issue with functions and classes.  Basically I want to
> bind functions to classes in multiple ways, and it's not working.

Yep.  When a function is set as a *class* attribute, it morphs into an
unbound method ("self is prepended", as you say), but when it's set as
an *instance* attribute, that does not happen.

> Is there any way to make this work?

Sure, there are a zillion ways.  Simplest, I think, is to wrap the
functions you want to set into a callable that isn't a function --
an instance of a class with a __call__ method being easiest IMHO.
Cfr:

>>> class calit:
...  def __init__(self, thefun):
...   self.thefun=thefun
...  def __call__(self, *pos, **kw):
...   apply(self.thefun, pos, kw)
...
>>> def pip(): print "Pip here!"
...
>>> def pip1(feep): print "Pip1 here:",feep
...
>>> class Pep: pass
...
>>> pap=Pep()
>>> pap.fun=calit(pip1)
>>> pap.fun('Ciao!')
Pip1 here: Ciao!
>>> Pep.fon=calit(pip1)
>>> pap.fon('Ciao!')
Pip1 here: Ciao!
>>>

Since the class attribute pep.fon and the instance attribute
pep.fun are both instances of the calit class, and not true
functions, there is no morphing, and you call them just the
same way on an instance.

If you dislike having to explicitly wrap the function into
the wrapper classi (fee.fie=foo(fum) like), it's of course
easy to hide the wrapping as part of __setattr__ (for the
instance attributes) -- not quite so trivial for the setting
of class attributes, though... you can't just to it with
normal binding syntax Classname.newattribute=somefunction,
I think -- unless, perhaps, you get into metaclasses for the
purpose (but I disclaim any understanding of metaclasses'
current status in Python, if any!-).

There's no dearth of applicable syntax sugar you might choose,
though -- e.g.:

def setfun(klass_or_obj, attname, funct):
    setattr(klass_or_obj, attname, calit(funct))

This will work for setting (wrapped) functions as either
class or instance attributes; and you may get subtler,
testing klass_or_obj's and funct's types and only doing
the wrapping if/when really necessary, etc, etc.


Alex






More information about the Python-list mailing list