Frage

I am writing a python API/server to allow an external device (microcontroller) to remotely call methods of an object by sending a string with the name of the method. These methods would be stored in a dictionary. e.g. :

class Server:
    ...
    functions = {}
    def register(self, func):
        self.functions[func.__name__] = func
    def call(self, func_name, args):
        self.functions[func_name](*args)
    ...

I know that I could define functions externally to the class definition and register them manually, but I would really like that the registering step would be done automatically. Consider the following class:

class MyServer(Server):
    ...
    def add(self,a,b):
        print a+b
    def sub(self,a,b):
        print a-b
    ...

It would work by subclassing a server class and by defining methods to be called. How could I get the methods to be automatically registered in the functions dictionary?

One way that I thought it could be done is with a metaclass that look at a pattern in the methods name add if a match is found, add that methods to the functions dictionary. It seems overkill...

Would it be possible to decorate the methods to be registered? Can someone give me a hint to the simplest solution to this problem?

War es hilfreich?

Lösung

There is no need to construct a dictionary, just use the getattr() built-in function:

   def call(self, func_name, args):
        getattr(self, func_name)(*args)

Python actually uses a dictionary to access attributes on objects anyway (it's called __dict__, - but using getattr() is better than accessing it directly).

If you really want to construct that dict for some reason, then look at the inspect module:

def __init__(self, ...):
    self.functions = dict(inspect.getmembers(self, inspect.ismethod))

If you want to pick specific methods, you could use a decorator to do that, but as BrenBarn points out, the instance doesn't exist at the time the methods are decorated, so you need to use the mark and recapture technique to do what you want.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top