2017-01-02 88 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.

有可能做到這一點更Python的方式。但是,這工作正常,以及:)