2016-07-24 11 views
0

Sagen wir, ich habe einige sehr lange Funktion module.my_function, die ungefähr so ​​ist:Python - Verwenden Sie externe Funktion als Klassenmethode

Mit einer großen Anzahl von Argumenten und Keyword-args. Ich möchte, dass diese Funktion sowohl als Teil des Moduls module als auch als Klassenmethode für myClass verwendbar ist. Der Code für die Funktion bleibt genau gleich, aber in myClass können einige Schlüsselwort-Argumente andere Standardwerte annehmen.

Was ist der beste Weg, dies zu tun? Früher war ich so etwas wie tun:

class myCLass(object): 
    def __init__(self,... 
    def my_function(self, param1,param2,param3='hello',param4='qaz',param5=['baz'],...): 
     module.my_function(param1,param2,param3=param3,param4=param4,param5=param5,...) 

scheint es ein wenig albern, all diese Argumente zu schreiben, dass viele Male, vor allem mit einer sehr großen Anzahl von Argumenten. Ich habe auch überlegt, etwas wie module.my_function(**locals()) innerhalb der Klassenmethode zu tun, aber ich bin mir nicht sicher, wie man mit dem self Argument umgehen soll und ich weiß nicht, ob dies zu anderen Problemen führen würde.

Ich konnte nur kopieren Sie den gesamten Code für die Funktion einfügen, aber das wirklich scheint nicht sehr effizient, wenn alles, was zu ändern ist schon ein paar Standardwerte und der Code für my_function ist sehr lang. Irgendwelche Ideen?

+0

Gibt es einen Grund, dass alle der Keyword-args explizit sein müssen und Sie können nicht nur kwargs benutzen? – James

+0

Der Grund ist wahrscheinlich, dass ich einen Coder nicht zu erfahren bin ... Wie würde ich Kwargs in dieser Situation verwenden und einige der Standardwerte auf etwas anderes setzen? Sprich 3-5 im obigen Beispiel sind diejenigen, die ich verändere .. würde ich nur Params 1-5 angeben und Kwargs für den Rest verwenden? – dieggsy

Antwort

1

Sie die Funktion gebundene Methode umwandeln kann seine __get__ Methode unter der Rufnummer (da alle Funktion als descriptors auch, damit diese Methode haben)

def t(*args, **kwargs): 
    print(args) 
    print(kwargs) 

class Test(): 
    pass 
Test.t = t.__get__(Test(), Test) # binding to the instance of Test 

Zum Beispiel

Test().t(1,2, x=1, y=2) 
(<__main__.Test object at 0x7fd7f6d845f8>, 1, 2) 
{'y': 2, 'x': 1} 

Beachten Sie, dass die Instanz wird auch als Positionsargument übergeben. Wenn Sie wollen, dass Ihre Funktion eine Instanzmethode ist, sollte die Funktion so geschrieben sein, dass sich das erste Argument als Instanz der Klasse verhält. Andernfalls können Sie die Funktion an keine Instanz und die Klasse binden, die wie staticmethod sein wird.

Test.tt = t.__get__(None, Test) 
Test.tt(1,2,x=1, y=2) 
(1, 2) 
{'y': 2, 'x': 1} 

Darüber hinaus machen es zu einem classmethod (erstes Argument Klasse):

Test.ttt = t.__get__(Test, None) # bind to class 
Test.ttt(1,2, x=1, y=2) 
(<class '__main__.Test'>, 1, 2) 
{'y': 2, 'x': 1} 
Verwandte Themen