Python: ¿definiendo mis propios operadores?

80

Me gustaría definir mi propio operador. ¿Python admite tal cosa?

cwj
fuente
Bueno, podría tener un operador que no está definido (como $) y luego usar un código de Python para editarse (con open) y cambiar todo a $ bafunction(a,b)
whackamadoodle3000

Respuestas:

40

No, no puede crear nuevos operadores. Sin embargo, si solo está evaluando expresiones, puede procesar la cadena usted mismo y calcular los resultados de los nuevos operadores.

Zifre
fuente
1
Consulte a continuación el conjunto de operadores anulables predefinidos de Python.
Palimondo
179

Si bien técnicamente no puede definir nuevos operadores en Python, este truco inteligente soluciona esta limitación. Te permite definir operadores infijos como este:

# 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
fuente
2
+1 Ese truco es bastante bueno, pero no creo que funcione en esta situación.
Zifre
9
Puede ser un truco interesante, pero no creo que sea una buena solución. Python no permite crear operadores propios, una decisión de diseño que se tomó por una buena razón y debe aceptarla en lugar de ver esto como un problema e inventar formas de solucionarlo. No es una buena idea luchar contra el idioma en el que está escribiendo el código. Si realmente lo desea, debe usar un idioma diferente.
DasIch
79
@DasIch No podría estar más en desacuerdo. No todos somos libres de elegir un idioma deliberadamente. Por otro lado, no veo por qué debería conformarme con las decisiones de diseño de otra persona si no estoy satisfecho. - ¡Excelente truco de hecho!
ThomasH
+1 Para un truco muy bueno, pero mi pregunta era más sobre si definir mis propios operadores es una característica en Python o no, no si es posible fingir tener nuevos operadores, y parece que la respuesta es no, no puedes definir nuevos operadores. Aunque esto se acerca bastante.
ArtOfWarfare
2
Simplemente combiné esto con pipefrom toolz. pip = Infix(lambda x,y: pipe(x,y)). entonces 8 |pip| range |pip| sum |pip| range. parece funcionar.
cantdutchthis
44

No, Python viene con un conjunto de operadores predefinidos, pero anulables .

dfa
fuente
1
Tengo curiosidad por saber cómo dfplyutiliza un -->operador: haciadatascience.com/…
Max Candocia
1
@MaxCandocia Por lo que puedo decir, no es así (ver documentos ). El ejemplo en esa publicación que usa -->parece ser psuedocode. La biblioteca en sí simplemente se sobrecarga >>.
Andrew Marshall
11

Sage proporciona esta funcionalidad, esencialmente utilizando el "truco inteligente" descrito por @Ayman Hourieh, pero incorporado en un módulo como decorador para dar una apariencia más limpia y funcionalidad adicional - puede elegir el operador para sobrecargar y por lo tanto el orden de evaluación.

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

Consulte la documentación de Sage y este ticket de seguimiento de mejoras para obtener más información.

Billyjmc
fuente
10

Si tiene la intención de aplicar la operación en una clase particular de objetos, puede simplemente anular el operador que coincida con su función más cercana ... por ejemplo, anular __eq__()anulará el ==operador para devolver lo que desee. Esto funciona para casi todos los operadores.

Sudhir Jonathan
fuente
9

Python 3.5 introduce el símbolo @de un operador adicional.

PEP465 introdujo este nuevo operador para la multiplicación de matrices, para simplificar la notación de muchos códigos numéricos. El operador no se implementará para todos los tipos, sino solo para objetos similares a matrices.

Puede apoyar al operador para sus clases / objetos implementando __matmul__().

El PEP deja espacio para un uso diferente del operador para objetos no similares a matrices.

Por supuesto, puede implementar con @cualquier tipo de operación diferente de la multiplicación de matrices también para objetos similares a matrices, pero la experiencia del usuario se verá afectada, porque todos esperarán que su tipo de datos se comporte de una manera diferente.

gg349
fuente
¿Quiere decir que @es un nuevo símbolo de operador? ¿O que de alguna manera podemos usarlo para definir nuevos operadores propios?
Addem
Sí, @ es un nuevo símbolo de operador. Sí, puede usarlo para definir operaciones en sus objetos. Considere leer el PEP465.
gg349
5
@Addem Solo quiso decir que @es un nuevo operador. Eso es. El hecho sigue siendo: no puede definir sus propios operadores en Python.
John Red