I needed to define a universal class with some methods known at construction time. It has to be possible to check whether a method exists in the instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class C:
def __init__(self, methodNames):
for name in methodNames:
setattr(C, name, self.methodClosure(name))
def methodClosure(self, name):
def method(*args, **kwargs):
print name, args, kwargs
return method
# test code
if __name__ == "__main__":
c = C(['m1'])
print hasattr(c,'m1')
print hasattr(c,'m2')
c.m1(0, a=10)
c.m2(0, a=10)
# output of test code:
# True
# False
# m1 (<__main__.C instance at 0x12345678>, 0) {'a': 10}
# Traceback (most recent call last):
# File "test.py", line 16, in ?
# c.m2(0, a=10)
# AttributeError: C instance has no attribute 'm2'
|
I had a similar problem as the problem presented in recipe 307618 (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307618). This recipe was very helpful in finding the solution to my problem. My problem was different with respect to two aspects: 1. I know the methods the class has at construction time. 2. I need a class with methods for a set of names, but other methods must not exist. Reason: Another module checks whether some method to be called exists in the corresponding instance. The latter aspect required to modify recipe 307618. I applied the same trick, one method returns a closure with another method. Using setattr it is possible to assign a name to the method. This is done in the constructor. After having constructed the instance of class C in the example, it is possible to check the existence of a method in advance using hasattr.
setting methods for all instances. By putting the setattr code in __init__, you change all instances with each new instantiation of C:
Is this intentional? Seems like maybe you want a separate type for each set of methods instead. Perhaps something like: