Init a table of functions
Bengt Richter
bokr at oz.net
Sun Oct 10 03:43:22 EDT 2004
On Sun, 10 Oct 2004 03:56:13 GMT, Andrew Dalke <adalke at mindspring.com> wrote:
>Richard Blackwood wrote:
>> Yo Andrew. That doesn't work. Check my previous post w/ errors.
>
>What do you mean?
>
>Ahh, I see I solved the first problem (can't find 'foo')
>without solving what the OP wanted. Try this reordering.
>
>class foo:
> def f1():
> print "f1"
>
> def f2():
> print "f2"
>
> K={"f1" : f1,
> "f2" : f2,
> }
> f1 = staticmethod(f1)
> f2 = staticmethod(f2)
>
>def main():
> foo.K["f1"]()
> foo.K["f2"]()
>
>if __name__ == "__main__":
> main()
>
>The 'staticmethod' is a descriptor and only works in
>the context of a class.
Or where you force the issue as-if ;-)
>
>Functions get turned into methods only in the context
>of a class.
>
>So to use a function as a function, get it before it
>turns into a method or staticmethod.
Or make a custom descriptor K that invokes the getattr magic as if getting foo.f1
of foo().f1, and thus letting the staticmethod descriptor deliver the function. This
lets you generalize K to handle other kinds of class attributes as-if also.
If you wanted to exclude all but certain names allowed by K[name], you could do
that in __getitem__ by raising KeyError for the others.
This is for educational purposes only, not a general recommendation ;-)
>>> class foo(object):
... def f1():
... print "f1"
... f1=staticmethod(f1)
... def f2():
... print "f2"
... f2 = staticmethod(f2)
... def f3(*args):
... print 'method f3', args
... def f4(*args):
... print 'class method f4', args
... f4 = classmethod(f4)
... f5 = property(lambda *args:('property f5', args))
... class K(object):
... def __get__(self, inst, cls=None):
... if inst is None: self.obj=cls
... else: self.obj = inst
... return self
... def __getitem__(self, key):
... return getattr(self.obj, key)
... K = K()
...
>>> foo.f1
<function f1 at 0x0090C730>
>>> foo.K['f1']
<function f1 at 0x0090C730>
>>> foo.f1()
f1
>>> foo.K['f1']()
f1
>>> foo.K['f2']()
f2
>>> foo.f3
<unbound method foo.f3>
>>> foo.K['f3']
<unbound method foo.f3>
>>> foo.f3(foo())
method f3 (<__main__.foo object at 0x009015B0>,)
>>> foo.K['f3'](foo())
method f3 (<__main__.foo object at 0x009015B0>,)
>>> foo.f4
<bound method type.f4 of <class '__main__.foo'>>
>>> foo.K['f4']
<bound method type.f4 of <class '__main__.foo'>>
>>> foo.f4()
class method f4 (<class '__main__.foo'>,)
>>> foo.K['f4']()
class method f4 (<class '__main__.foo'>,)
>>> foo.f5
<property object at 0x0090E468>
>>> foo.K['f5']
<property object at 0x0090E468>
Ok, now via a foo instance:
>>> f = foo()
>>> f.f5
('property f5', (<__main__.foo object at 0x009015B0>,))
>>> f.K['f5']
('property f5', (<__main__.foo object at 0x009015B0>,))
>>> f.f1
<function f1 at 0x0090C730>
>>> f.K['f1']
<function f1 at 0x0090C730>
>>> f.K['f1']()
f1
>>> f.f3
<bound method foo.f3 of <__main__.foo object at 0x009015B0>>
>>> f.f3()
method f3 (<__main__.foo object at 0x009015B0>,)
>>> f.K['f3']
<bound method foo.f3 of <__main__.foo object at 0x009015B0>>
>>> f.K['f3']()
method f3 (<__main__.foo object at 0x009015B0>,)
Reminder that via the class, it's unbound:
>>> foo.K['f3']
<unbound method foo.f3>
The class method is bound to the class instance either way
>>> f.f4
<bound method type.f4 of <class '__main__.foo'>>
>>> f.K['f4']
<bound method type.f4 of <class '__main__.foo'>>
>>> f.K['f4']()
class method f4 (<class '__main__.foo'>,)
>>> foo.f4
<bound method type.f4 of <class '__main__.foo'>>
>>> foo.K['f4']
<bound method type.f4 of <class '__main__.foo'>>
>>> foo.K['f4']()
class method f4 (<class '__main__.foo'>,)
Regards,
Bengt Richter
More information about the Python-list
mailing list