2017-01-02 2 views
0

Wie kann ich Funktionen in einer Klasse in Python dynamisch erstellen, so dass ich tun kann;Dynamische Funktionserstellung in Klassen

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

dynamic_function Bedürfnisse braucht auch Optionen zu akzeptieren, die ich verwenden kann, wenn es aufgerufen wird.

+0

Was sollen die Funktionen * tun *? Wenn Sie sie nicht definieren, bevor Sie sie aufrufen, können Sie nichts leichter definieren und verstehen, als eine einzelne feste Methode zu definieren, die den "Namen" Ihrer dynamischen Funktion als Argument verwendet. – chepner

+0

@chepner Verwendung viele Aufrufe an verschiedene Teile einer API, wo Sie zum Beispiel die Funktionen in einer Schleife erstellen möchten. Unten finden Sie die Antworten für ein Beispiel. Beachten Sie, dass ich meine eigene Frage beantwortet habe, da dies eher eine "gut zu wissen" Lösung für diejenigen ist, die das nicht wussten – xeor

Antwort

0

Dies können Sie machen, dass

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)) 

die Ausgabe produzieren

tun:

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'] 

Eine reale Umsetzung ist (was sie nicht mehr verwenden) an here entfernt. Basierend auf der commitlog, der Grund dafür ist This allows us to add docstrings and stricter mypy annotations..

Es könnte eine mehr pythonische Art sein, dies zu tun. Aber das funktioniert auch gut :)

Verwandte Themen