2013-11-20 19 views
1

Я пишу API/сервер python, чтобы позволить внешнему устройству (микроконтроллеру) удаленно вызывать методы объекта, отправив строку с именем метода. Эти методы будут храниться в словаре. например :Python, выполнение дополнительного кода при определении метода

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

Я знаю, что я мог бы определить функции внешне определения класса и зарегистрировать их вручную, но я бы очень хотел, что шаг регистрации будет сделан автоматически. Рассмотрим следующий класс:

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

Это будет работать путем подкласса класса сервера и определения методов для вызова. Как я могу заставить методы автоматически регистрироваться в словаре функций?

Один из способов, которым я думал, что это можно сделать, - это метакласс, который смотрит на шаблон в имени методов, добавляя, если совпадение найдено, добавьте эти методы в словарь функций. Кажется, излишним ...

Можно ли украсить методы для регистрации? Может ли кто-нибудь дать мне подсказку для простейшего решения этой проблемы?

+1

Ваше решение для метакласса также может быть выполнено с помощью декоратора класса. Декоратор методов не сможет ничего хранить в классе, потому что класс не существует в то время, когда работает декодер метода. – BrenBarn

+0

@BrenBarn Существует [решение этой проблемы] (https://github.com/Lattyware/recap). –

+0

@ Lattyware: Конечно, я просто говорю, что вам понадобятся некоторые механизмы, кроме декоратора, по методам. – BrenBarn

ответ

0

Там нет необходимости строить словарь, просто использовать the getattr() built-in function:

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

Python фактически использует словарь для доступа атрибутов объектов в любом случае (это называется __dict__, - но с использованием getattr() лучше, чем доступ к нему напрямую).

Если вы действительно хотите, чтобы построить что Dict по какой-то причине, то посмотрите на the inspect module:

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

Если вы хотите выбрать конкретные методы, вы можете использовать декоратора, чтобы сделать это, но, как BrenBarn указывает , экземпляр не существует во время декодирования методов, поэтому вам нужно использовать the mark and recapture technique, чтобы делать то, что вы хотите.

+0

Действительно, это был бы лучший способ сделать это. Но тогда, как бы я напечатал список методов, определенных на MyServer, не сохраняя их в списке и не повторяя этот список? – Speccy

+0

@Speccy Если вам нужен список всех методов, посмотрите на 'inspect.getmembers()' - вторую половину моего ответа. –

Смежные вопросы