2017-01-02 4 views
0

Как я могу динамически создавать функции в классе на python, чтобы я мог это делать;Создание динамических функций в классах

client = Client() 
client.dynamic_function() 
client.another_dynamic_function(params=123) 

dynamic_function потребности необходимо также принимать параметры, которые можно использовать при вызове его.

+0

Каковы функции, которые предполагается * делать *? Если вы не определяете их до их вызова, вы не можете сделать ничего, что не так легко определить и понять, чем определить один фиксированный метод, который принимает «имя» вашей динамической функции в качестве аргумента. – chepner

+0

Использование @chepner - это много вызовов в разные части api, где, например, вы хотите создать функции в цикле. См. Ответы ниже. Обратите внимание, что я ответил на свой собственный вопрос, так как это скорее «хорошо знакомое» решение для тех, кто этого не знал – xeor

ответ

0

Это сделает вас в состоянии сделать это

class Client(object): 

    @classmethod 
    def _register(cls, name, **create_kwargs): 
     def func(**kwargs): 
      # Call your dynamic things in here... 
      return kwargs 

     def call(self, **kwargs): 
      print('calling dynamic function {name}, created with ({create_kwargs})) results being: {result}'.format(name=name, create_kwargs=create_kwargs, result=func(**kwargs))) 

     call.__name__ = name 
     setattr(cls, name, call) 

Client._register('dynamic1') 
Client._register('dynamic2', option=123) 


if __name__ == '__main__': 
    client = Client() 
    client.dynamic1() 
    client.dynamic1(something=111) 
    client.dynamic2() 
    client.dynamic2(something=222) 
    print(dir(client)) 

Производство вывод:

calling dynamic function dynamic1, created with ({})) results being: {} 
calling dynamic function dynamic1, created with ({})) results being: {'something': 111} 
calling dynamic function dynamic2, created with ({'option': 123})) results being: {} 
calling dynamic function dynamic2, created with ({'option': 123})) results being: {'something': 222} 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_register', 'dynamic1', 'dynamic2'] 

В реальном мире реализации (которые они не используют больше) расположен в here. На основании commitlog причиной является This allows us to add docstrings and stricter mypy annotations..

Возможно, существует более питонический способ сделать это. Но это прекрасно работает :)

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