Estoy trabajando con Python y siempre que tuve que validar la entrada de la función, asumí que la entrada funcionó y luego detecté errores.
En mi caso, tuve una clase de Vector()
universal que usé para algunas cosas diferentes, una de las cuales es la sum. Funcionó como una clase Color()
y como Vector()
, así que cuando agrego un escalar al Color()
, debería agregar esa constante a cada componente individual. Vector()
adición de Vector()
y de Vector()
requirió la adición de componentes.
Este código se usa para un trazador de rayos, por lo que cualquier aumento de velocidad es excelente.
Aquí hay una versión simplificada de mi clase Vector()
:
class Vector: def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __add__(self, other): try: return Vector(self.x + other.x, self.y + other.y, self.z + other.z) except AttributeError: return Vector(self.x + other, self.y + other, self.z + other)
Actualmente estoy usando el método try...except
. ¿Alguien sabe de un método más rápido?
EDITAR: Gracias a las respuestas, probé y probé la siguiente solución, que comprueba específicamente el nombre de una clase antes de agregar los objetos Vector()
:
class Vector: def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __add__(self, other): if type(self) == type(other): return Vector(self.x + other.x, self.y + other.y, self.z + other.z) else: return Vector(self.x + other, self.y + other, self.z + other)
Hice una prueba de velocidad con estos dos bloques de código usando timeit
, y los resultados fueron bastante significativos:
1.0528049469 usec/pass for Try...Except 0.732456922531 usec/pass for If...Else Ratio (first / second): 1.43736090753
No he probado la clase Vector()
sin ninguna validación de entrada (es decir, moviendo la comprobación de la clase al código real), pero me imagino que es incluso más rápido que el método if...else
.
Actualización tardía : Mirando hacia atrás en este código, esta no es una solución óptima.
OOP hace esto aún más rápido:
class Vector: def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __add__(self, other): return Vector(self.x + other.x, self.y + other.y, self.z + other.z) class Color(Vector): def __add__(self, other): if type(self) == type(other): return Color(self.x + other.x, self.y + other.y, self.z + other.z) else: return Color(self.x + other, self.y + other, self.z + other)
Aprecié la respuesta de Matt Joiner, pero quería incluir algunas observaciones adicionales para aclarar que, junto con un par de otros factores, hay 4 veces más importantes al elegir entre las condiciones de verificación previa (conocidas como LBYL o “Mire antes de saltar” “) y solo manejar las excepciones (conocidas como EAFP o” Más fácil de pedir perdón que el permiso “).
Esos tiempos son:
Los factores adicionales son:
Ese último punto es el que debe abordarse primero: si existe un potencial para una condición de carrera, entonces no tiene otra opción, debe usar el manejo de excepciones. Un ejemplo clásico es:
if : # May still fail if another process creates the target dir
Dado que LBYL no descarta que la excepción sea en tales casos, no ofrece un beneficio real y no hay que hacer un juicio: EAFP es el único enfoque que manejará la condición de la carrera correctamente.
Pero si no hay una condición de raza, cualquiera de los dos enfoques es potencialmente viable. Ofrecen diferentes compensaciones:
Eso lleva a los siguientes criterios de decisión:
Como regla general:
* Las personas variarán en cuanto a lo que consideran “la mayor parte del tiempo” en este contexto. Para mí, si espero que la operación tenga éxito más de la mitad del tiempo, simplemente usaría EAFP como una cuestión de rutina, hasta que tuviera razones para sospechar que este fragmento de código era un cuello de botella real en el rendimiento.
En Python, las excepciones suelen ser más rápidas debido a la cantidad reducida de búsquedas. Sin embargo, un amigo dijo una vez (y debería aplicarse a cualquier idioma), pretender que cada vez que se detecta una excepción, hay un pequeño retraso. Evite usar excepciones donde un retraso pueda ser un problema.
En el ejemplo que has dado, me gustaría ir con la excepción.