How To Store Function In Class Attribute?
Solution 1:
You could just add it as a plain old attribute?
defmy_filter_func(x):
return x % 2 == 0classFilterClass(object):def__init__(self):
self.filter_func = my_filter_func
deffilter_data(self, data):
return filter(self.filter_func, data)
Alternatively, force it to be a staticmethod:
defmy_filter_func(x):
return x % 2 == 0classFilterClass(object):
filter_func = staticmethod(my_filter_func)
deffilter_data(self, data):
returnfilter(self.filter_func, data)
Solution 2:
Python has a lot of magic within. One of those magics has something to do with transforming functions into UnboundMethod objects (when assigned to the class, and not to an class' instance).
When you assign a function (And I'm not sure whether it applies to any callable or just functions), Python converts it to an UnboundMethod object (i.e. an object which can be called using an instance or not).
Under normal conditions, you can call your UnboundMethod as normal:
def myfunction(a, b):
return a + b
classA(object):
a = myfunction
A.a(1, 2)
#prints 3
This will not fail. However, there's a distinct case when you try to call it from an instance:
A().a(1, 2)
This will fail since when an instance gets (say, internal getattr
) an attribute which is an UnboundMethod, it returns a copy of such method with the im_self
member populated (im_self
and im_func
are members of UnboundMethod). The function you intended to call, is in the im_func
member. When you call this method, you're actually calling im_func
with, additionally, the value in im_self
. So, the function needs an additional parameter (the first one, which will stand for self).
To avoid this magic, Python has two possible decorators:
- If you want to pass the function as-is, you must use
@staticmethod
. In this case, you will have the function not converted to UnboundMethod. However, you will not be able to access the calling class, except as a global reference. - If you want to have the same, but be able to access the current class (disregarding whether the function it is called from an instance or from a class), then your function should have another first argument (INSTEAD of self: cls) which is a reference to the class, and the decorator to use is
@classmethod
.
Examples:
class A(object):
a = staticmethod(lambda a, b: a + b)
A.a(1, 2)
A().a(1, 2)
Both will work.
Another example:
def add_print(cls, a, b):
print cls.__name__
return a + b
class A(object):
ap = classmethod(add_print)
class B(A):
pass
A.ap(1, 2)
B.ap(1, 2)
A().ap(1, 2)
B().ap(1, 2)
Check this by yourseld and enjoy the magic.
Post a Comment for "How To Store Function In Class Attribute?"