Init a table of functions

Bengt Richter bokr at oz.net
Sun Oct 10 09:43:22 CEST 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