[Tutor] Problem with calling class methods stored in a list
Peter Otten
__peter__ at web.de
Fri Jan 11 10:58:51 CET 2013
Tobias M. wrote:
> Am 10.01.2013 15:15, schrieb Peter Otten:
>> Of course handle_1_42() is not exactly the method name one would hope
>> for. You could, again, strive for simplicity and add a lookup table that
>> maps protocol tuples to function /names/ , but as simplicity doesn't seem
>> to be your cup of tea:
>>
>> class HandlersType(type):
>> def __init__(cls, name, bases, classdict):
>> cls.lookup_protocol = lookup = {}
>> for k, v in classdict.items():
>> if isinstance(v, protocol_method):
>> lookup[v.protocol] = getattr(cls, k)
>>
>> class protocol_method(classmethod):
>> pass
>>
>> def protocol(x, y):
>> def attach_protocol(f):
>> f = protocol_method(f)
>> f.protocol = x, y
>> return f
>> return attach_protocol
>>
>> class D:
>> __metaclass__ = HandlersType
>>
>> @protocol(42, 17)
>> def foo(cls):
>> print "Hi"
>>
>> D.lookup_protocol[42, 17]()
>>
>> ;)
>>
> In my eyes this is anything but simple.
> Correct me if I'm wrong:
> I already use a lookup table in my code, called "method_list" in my
> first post. The advantage of your above code is that I don't need to
> manually take care of the lookup table and extension by subclassing is
> easier.
You are right; the misunderstanding is that I wasn't advertising the above
"fancy" solution (which is buggy, btw).
I have now implemented what I had in mind with the protocol to function name
mapping, and I think /that/ is reasonably complex. I'm using instance
methods in the demo, but it should work with class methods as well.
class Error(Exception):
def __init__(self, protocol):
Exception.__init__(self, self.template.format(protocol))
class UnknownProtocolError(Error):
template = "Unknown protocol {}"
class ProtocolNotSupportedError(Error):
template = "Protocol {} not supported"
FOO = (42, 17)
BAR = (1, 2)
BAZ = (3, 4)
HAM = (4, 5)
SPAM = (5, 6)
class HandlersBase(object):
protocol_to_methodname = {
FOO: "foo",
BAR: "bar",
BAZ: "baz",
HAM: "ham",
}
def get_handler(self, protocol):
try:
methodname = self.protocol_to_methodname[protocol]
except KeyError:
raise UnknownProtocolError(protocol)
method = getattr(self, methodname, None)
if method is None:
raise ProtocolNotSupportedError(protocol)
return method
class A(HandlersBase):
def foo(self): print "A.foo"
def bar(self): print "A.bar"
def baz(self): print "A.baz"
class B(A):
def bar(self): print "B.bar"
baz = None # hide parent implementation
if __name__ == "__main__":
for Class in A, B:
inst = Class()
print "---", Class.__name__, "---"
for protocol in FOO, BAR, BAZ, SPAM:
try:
inst.get_handler(protocol)()
except Error as err:
print err
More information about the Tutor
mailing list