Python: Meine eigenen Operatoren definieren?


80

Ich möchte meinen eigenen Operator definieren. Unterstützt Python so etwas?


Nun, Sie könnten einen Operator haben, der nicht definiert ist (wie $) und dann etwas Python-Code verwenden, um sich selbst (mit open) zu bearbeiten und alles a $ binfunction(a,b)
whackamadoodle3000

Antworten:


40

Nein, Sie können keine neuen Operatoren erstellen. Wenn Sie jedoch nur Ausdrücke auswerten, können Sie die Zeichenfolge selbst verarbeiten und die Ergebnisse der neuen Operatoren berechnen.


1
Siehe unten für Pythons Satz vordefinierter overridable Satz von Operatoren.
Palimondo

179

Während Sie in Python technisch gesehen keine neuen Operatoren definieren können, umgeht dieser clevere Hack diese Einschränkung. Sie können Infix-Operatoren wie folgt definieren:

# simple multiplication
x=Infix(lambda x,y: x*y)
print 2 |x| 4
# => 8

# class checking
isa=Infix(lambda x,y: x.__class__==y.__class__)
print [1,2,3] |isa| []
print [1,2,3] <<isa>> []
# => True

2
+1 Dieser Hack ist ziemlich cool, aber ich denke nicht, dass er in dieser Situation funktionieren wird.
Zifre

9
Es mag ein interessanter Hack sein, aber ich denke nicht, dass dies eine gute Lösung ist. Python erlaubt es nicht, eigene Operatoren zu erstellen, eine Entwurfsentscheidung, die aus einem guten Grund getroffen wurde, und Sie sollten sie akzeptieren, anstatt dies als Problem zu betrachten und Wege zu finden, um es zu umgehen. Es ist keine gute Idee, gegen die Sprache zu kämpfen, in der Sie den Code schreiben. Wenn Sie wirklich wollen, sollten Sie eine andere Sprache verwenden.
DasIch

79
@DasIch Ich könnte nicht mehr widersprechen. Es steht uns nicht allen frei, bewusst eine Sprache zu wählen. Auf der anderen Seite verstehe ich nicht, warum ich mich mit den Designentscheidungen anderer zufrieden geben sollte, wenn ich nicht zufrieden bin. - Ausgezeichneter Hack!
ThomasH

+1 Für einen sehr coolen Hack, aber meine Frage war eher, ob das Definieren meiner eigenen Operatoren eine Funktion in Python ist oder nicht, nicht, ob es möglich ist, neue Operatoren zu fälschen, und es scheint, dass die Antwort Nein ist, das können Sie nicht neue Operatoren definieren. Obwohl dies verdammt nahe kommt.
ArtOfWarfare

2
Ich habe das gerade mit pipevon kombiniert toolz. pip = Infix(lambda x,y: pipe(x,y)). dann 8 |pip| range |pip| sum |pip| range. scheint zu funktionieren.
Cantdutchthis


11

Sage bietet diese Funktionalität im Wesentlichen unter Verwendung des von @Ayman Hourieh beschriebenen "cleveren Hacks", der jedoch als Dekorateur in ein Modul integriert wurde, um ein saubereres Erscheinungsbild und zusätzliche Funktionen zu erzielen. Sie können den zu überladenden Bediener und damit die Reihenfolge der Auswertung auswählen.

from sage.misc.decorators import infix_operator

@infix_operator('multiply')
def dot(a,b):
    return a.dot_product(b)
u=vector([1,2,3])
v=vector([5,4,3])
print(u *dot* v)
# => 22

@infix_operator('or')
def plus(x,y):
    return x*y
print(2 |plus| 4)
# => 6

Weitere Informationen finden Sie in der Sage-Dokumentation und in diesem Erweiterungsverfolgungsticket .


10

Wenn Sie beabsichtigen, die Operation auf eine bestimmte Klasse von Objekten anzuwenden, können Sie einfach den Operator überschreiben, der Ihrer Funktion am nächsten kommt. Durch Überschreiben __eq__()wird beispielsweise der ==Operator überschrieben , um das zurückzugeben, was Sie möchten. Dies funktioniert für fast alle Bediener.


9

Python 3.5 führt das Symbol @für einen zusätzlichen Operator ein.

PEP465 führte diesen neuen Operator für die Matrixmultiplikation ein, um die Notation vieler numerischer Codes zu vereinfachen. Der Operator wird nicht für alle Typen implementiert, sondern nur für Arrays-ähnliche Objekte.

Sie können den Operator für Ihre Klassen / Objekte durch Implementierung unterstützen __matmul__().

Das PEP lässt Platz für eine andere Verwendung des Operators für nicht Arrays-ähnliche Objekte.

Natürlich können Sie mit @jeder Art von Operation, die sich von der Matrixmultiplikation unterscheidet, auch für arraysähnliche Objekte implementieren , aber die Benutzererfahrung wird beeinträchtigt, da jeder erwartet, dass sich Ihr Datentyp anders verhält.


Meinen Sie nur, dass dies @ein neues Operatorsymbol ist? Oder dass wir es irgendwie verwenden können, um eigene neue Operatoren zu definieren?
Addem

Ja, @ ist ein neues Operatorsymbol. Ja, Sie können damit Vorgänge für Ihre Objekte definieren. Lesen Sie den PEP465.
gg349

5
@Addem Er meinte nur, dass dies @ein neuer Operator ist. Das ist es. Die Tatsache bleibt weiterhin bestehen: Sie können in Python keine eigenen Operatoren definieren.
John Red
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.