[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