1

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?

3
  • 1
    Your metaclass solution could also be done with a class decorator. A decorator on the methods won't be able to store anything on the class because the class doesn't exist yet at the time a method decorator runs.
    – BrenBarn
    Commented Nov 20, 2013 at 21:42
  • @BrenBarn There is a solution to that issue. Commented Nov 20, 2013 at 23:31
  • @Lattyware: Sure, I'm just saying you'll need some machinery besides a decorator on the methods.
    – BrenBarn
    Commented Nov 21, 2013 at 3:13

1 Answer 1

0

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.

2
  • Indeed, this would be a better way to do it. But then, how would I print a list of methods defined in MyServer without storing them in a list and iterating over that list?
    – Speccy
    Commented Nov 20, 2013 at 22:01
  • @Speccy If you want a list of all the methods, take a look at inspect.getmembers() - the second half of my answer. Commented Nov 20, 2013 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.