2011-01-15 6 views
47

Zum Beispiel — sagen ich möchte eine helloWorld() Methode zu Python dict Typ hinzufügen. Darf ich das machen?Kann ich den integrierten Python-Typen benutzerdefinierte Methoden/Attribute hinzufügen?

JavaScript hat ein Prototyp-Objekt, das sich so verhält. Vielleicht ist es ein schlechtes Design und ich sollte das dict-Objekt ableiten, aber dann funktioniert es nur für die Unterklassen und ich möchte, dass es in allen zukünftigen Wörterbüchern funktioniert.

Hier ist, wie es in JavaScript nach unten gehen würde:

String.prototype.hello = function() { 
    alert("Hello, " + this + "!"); 
} 
"Jed".hello() //alerts "Hello, Jed!" 

Hier ist eine nützliche Verbindung mit weiteren Beispielen — http://www.javascriptkit.com/javatutors/proto3.shtml

+0

Sie können dies auch in Ruby tun, indem Sie die Klasse einfach wieder öffnen, dh: class String; def new_method() ...; Ende; Ich bin mir ziemlich sicher, dass Python auch so etwas hat. –

+0

@Abdullah Ich glaube, Sie beziehen sich auf Affe Patching, die meist verpönt ist. –

+0

Ja genau. Es ist überall in Rails gemacht. –

Antwort

53

Sie können die Methode nicht direkt zum Originaltyp hinzufügen. Sie können den Typ jedoch ableiten und ihn dann im integrierten/globalen Namespace ersetzen, wodurch der gewünschte Effekt erzielt wird. Leider werden Objekte, die mit der Literalsyntax erstellt wurden, weiterhin vom Vanilla-Typ sein und haben keine neuen Methoden/Attribute.

Hier ist, wie es aussieht

# Built-in namespace 
import __builtin__ 

# Extended subclass 
class mystr(str): 
    def first_last(self): 
     if self: 
      return self[0] + self[-1] 
     else: 
      return '' 

# Substitute the original str with the subclass on the built-in namespace  
__builtin__.str = mystr 

print str(1234).first_last() 
print str(0).first_last() 
print str('').first_last() 
print '0'.first_last() 

output = """ 
14 
00 

Traceback (most recent call last): 
    File "strp.py", line 16, in <module> 
    print '0'.first_last() 
AttributeError: 'str' object has no attribute 'first_last' 
""" 
+0

Ich denke, ich muss nur die bevorzugte Methode der Unterklassenbildung verwenden. Vielleicht werde ich es lieben. – jedmao

+11

Hinweis: Das Modul "__builtin__" wurde in Python3 in "Builtins" umbenannt. – changokun

+0

Nun, ich habe ein Problem in Python 2 gefunden. Danach kann ich nicht mehr nach dem Typ suchen> type ('') == str false <. Wenn ich ("") tippe, bekomme ich , aber irgendwie funktioniert der Vergleich nicht mehr. Bevor Sie die 'Zeile __builtin __. Str = mystr' ausführen, funktioniert die Überprüfung nach Typ. – Nadu

1

Ja, durch diese Art von Unterklassen. Siehe unifying types and classes in Python.

Nein, dies bedeutet nicht, dass tatsächliche dicts diesen Typ haben, denn das wäre verwirrend. Das Unterklassifizieren eines integrierten Typs ist die bevorzugte Vorgehensweise zum Hinzufügen von Funktionalität.

+5

Das wäre verwirrend und sehr sehr nützlich. –

+0

@EvgeniSergeev Warum denken Sie, dass es sehr, sehr nützlich wäre? Ich habe nie wirklich jene Leute verstanden, die sich das wünschen. Denkst du, 5 sollte nicht vom Typ int sein, oder denkst du, dass Typ int veränderlich sein sollte (während 5 selbst unveränderlich ist)? – Veky

+0

@Veky Ich möchte 'any_dictionary_instance.len()' oder '.size()', zusätzlich zu den verfügbaren 'any_dictionary_instance .__ len __()' und 'len (any_dictionary_instance)', die es aufruft. Die Größe ist semantisch eine Eigenschaft von Containern, daher ist es bequemer zu schreiben, wie Sie z.B. "iterieren von 0 bis zur Objektgröße" ... oops, kann das nicht ausdrücken, die Sprache zwingt mich dazu, sie neu zu formulieren als "iteriere von 0 bis zur Größe des Objekts". Aus nichts anderem als aus historischen Gründen, nehme ich an. –

-1

Subclassing der Weg in Python zu gehen. Polyglot-Programmierer lernen, das richtige Werkzeug für die richtige Situation zu verwenden - im Rahmen des Zumutbaren. Etwas, das so kunstvoll konstruiert ist wie Rails (ein DSL mit Ruby), ist schmerzhaft schwierig in einer Sprache mit einer strengeren Syntax wie Python zu implementieren. Die Leute vergleichen oft die beiden und sagen, wie ähnlich sie sind. Der Vergleich ist etwas unfair. Python glänzt auf seine Weise. totochto.

Verwandte Themen