Python: Meine eigenen Operatoren definieren?

80

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

cwj
quelle
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.

Zifre
quelle
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
Ayman Hourieh
quelle
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
44

Nein, Python wird mit einer vordefinierten, aber überschreibbaren Reihe von Operatoren geliefert .

dfa
quelle
1
Ich bin neugierig zu wissen, wie dfplyein -->Operator verwendet wird: intodatascience.com/…
Max Candocia
1
@ MaxCandocia Soweit ich das beurteilen kann, ist dies nicht der Fall (siehe Dokumentation ). Das Beispiel in diesem Beitrag, das verwendet wird, -->scheint Pseudocode zu sein. Die Bibliothek selbst ist nur überlastet >>.
Andrew Marshall
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 .

billyjmc
quelle
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.

Sudhir Jonathan
quelle
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.

gg349
quelle
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