Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispatch a class method

Tags:

python

Given the below piece of code how do you correctly dispatch a class method:

>>> class A:
...     def a(self):
...         pass
...     def b(self):
...         pass
...     c = a
...     dispatch_map = { 'a' : a, 'b' : b }
...     def dispatch(self, arg):
...         self.dispatch_map[arg]()   # Fail: unbound method!
>>> A().c
<bound method A.a of <__main__.A object at 0x100550210>>
>>> A().dispatch_map['a']
<function a at 0x10054acf8>

Why is c a bound method, whereas dispatch_map['a'] is an unbound method. This is simple with plain functions, and is a common idiom for a select/case replacement, what is the correct way to do this with class methods?

like image 827
AChampion Avatar asked Dec 16 '22 05:12

AChampion


1 Answers

You can only bind a method when there is an instance to bind to. Your dispatch map builds the map with just the class instead.

Build the map in __init__:

def __init__(self):
    self.dispatch_map = { 'a' : self.a, 'b' : self.b }

or bind the methods explicitly in your dispatch() method:

def dispatch(self, arg):
    bound = self.dispatch_map[arg].__get__(self, type(self))
    bound()

This uses the descriptor protocol to bind the method, which is what normally happens when a method is looked up on an instance.

like image 153
Martijn Pieters Avatar answered Dec 21 '22 22:12

Martijn Pieters