[Baypiggies] Assigning functions as class variables

AM ams.fwd at gmail.com
Sat May 31 06:34:33 CEST 2014


That was great. Thanks.

On 05/30/2014 09:30 PM, Simeon Franklin wrote:
> tl;dr - wrap your new functions in staticmethod and it should work.
>
> A function attached to a class is a method. If you reference a method 
> attached to a class it is an unbound method - a method of a class but 
> not bound to a particular object. If you refer to it on an 
> instanciated object it is bound to that object.
>
> >>> class Foo(object):
> ...     def method(self):
> ...         pass
> ...
> >>> Foo.method
> <unbound method Foo.method>
> >>> obj = Foo()
> >>> obj.method
> <bound method Foo.method of <__main__.Foo object at 0x10a2dd2d0>>
>
> Either way Python checks methods for the presence of the "self" 
> argument and it has to be the right kind of thing - an instance of the 
> class.
>
> If you don't like this and just want a plain old function you can get 
> it to work by using the staticmethod decorator which takes a method 
> and does something complicated to get around normal function 
> invocation rules. If I remember it correctly staticmethod actually 
> wraps your function in a callable object but how it does it isn't that 
> important - it's easy to use.
>
> >>> Foo.pof = lambda : 1  # just using lambda to save space. This could 
> be any Plain Old Function
> >>> Foo.pof()
> Traceback (most recent call last):
>   File "<ipython-input-16-9b1e0ee0f6b1>", line 1, in <module>
>     Foo.pof()
> TypeError: unbound method <lambda>() must be called with Foo instance 
> as first argument (got nothing instead)
> >>> Foo.pof = staticmethod(lambda : 1)  # but if I wrap it in staticmethod
> >>> Foo.pof()  # I'm ok to call it without passing an instance of Foo
> 1
>
> Hope that helped!
>
> -regards
> Simeon Franklin
>
>
>
> On Fri, May 30, 2014 at 8:51 PM, AM <ams.fwd at gmail.com 
> <mailto:ams.fwd at gmail.com>> wrote:
>
>     Hi.
>
>     What I am trying to do is assign a function to a class variable
>     and use it. For e.g.:
>
>
>     def foo(a):
>         print a
>
>     class X(object):
>
>         @classmethod
>         def bar(cls, fn):
>             cls.fn = fn
>
>         @classmethod
>         def baz(cls, a):
>             cls.fn(a)
>
>
>     X.bar(foo)
>     X.baz(12)
>
>     If I run this I get:
>     TypeError: unbound method foo() must be called with X instance as
>     first argument (got int instance instead)
>
>     I sort of understand why allowing this might cause a bit of
>     trouble as fn could be an unbound method which receives X as the
>     first argument, however I don't quite understand this particular
>     error.
>
>     Changing foo to accept another argument also does not work. If
>     someone could enlighten me about:
>
>     1. Why exactly is calling the method disallowed in pretty much all
>     forms?
>
>     2. How do people work around this?
>
>     that would be great.
>
>     Thanks.
>     AM
>     _______________________________________________
>     Baypiggies mailing list
>     Baypiggies at python.org <mailto:Baypiggies at python.org>
>     To change your subscription options or unsubscribe:
>     https://mail.python.org/mailman/listinfo/baypiggies
>
>



More information about the Baypiggies mailing list