Recientemente leí las preguntas que recomiendan no usar las sentencias de cambio de mayúsculas y minúsculas en los idiomas que sí lo admiten. Por lo que va Python, he visto una serie de reemplazos de casos de conmutación, tales como:Elegir entre diferentes reemplazos de conmutadores en Python - dictionary o if-elif-else?
- uso de un diccionario (Muchas variantes)
- Usando una tupla
- El uso de un decorador de la función (http://code.activestate.com/recipes/440499/)
- Utilización de polimorfismo (método recomendado en lugar de la verificación de tipos de objetos)
- el uso de un si-elif-else escalera
- Alguien incluso se recomienda el patrón de visitantes (Posiblemente extrínseca)
Dada la amplia variedad de opciones, tengo un poco de dificultad para decidir qué hacer con un código en particular. Me gustaría aprender los criterios para seleccionar uno de estos métodos sobre el otro en general. Además, agradecería consejos sobre qué hacer en los casos específicos en los que tengo problemas para decidir (con una explicación de la elección).
Aquí está el problema específico:
(1)
def _setCurrentCurve(self, curve):
if curve == "sine":
self.currentCurve = SineCurve(startAngle = 0, endAngle = 14,
lineColor = (0.0, 0.0, 0.0), expansionFactor = 1,
centerPos = (0.0, 0.0))
elif curve == "quadratic":
self.currentCurve = QuadraticCurve(lineColor = (0.0, 0.0, 0.0))
Este método es llamado por un qt-ranura en respuesta a elegir para dibujar una curva de un menú. El método anterior contendrá un total de 4-7 curvas una vez que la aplicación esté completa. ¿Está justificado usar un diccionario desechable en este caso? Dado que la forma más obvia de hacerlo es if-elif-else, ¿debería seguir así? También he considerar el uso ** Kargs aquí (con una ayuda amigos) ya que todas las clases de curvas utilizan ** Kargs ...
(2)
Esta segunda pieza de código es un qt-ranura que es llamado cuando el usuario cambia una propiedad de una curva. Básicamente, la ranura toma los datos del gui (spinBox) y los coloca en una variable de instancia de la clase de curva apropiada. En este caso, nuevamente tengo la misma pregunta: ¿Debería usar un dict?
Aquí es el ya mencionado de ranura
def propertyChanged(self, name, value):
"""A Qt slot, to react to changes of SineCurve's properties."""
if name == "amplitude":
self.amplitude = value
elif name == "expansionFactor":
self.expansionFactor = value
elif name == "startAngle":
self.startAngle = value
elif name == "endAngle":
self.endAngle = value
Para referencia, aquí es el código para la conexión a la anterior ranura -
def _connectToPage(self, page):
for connectionData in page.getConnectibles():
self.connect(connectionData["object"],
SIGNAL(connectionData["signal"]),
lambda value, name = connectionData["property"]:\
self.currentCurve.propertyChanged(name, value))
self.connect(connectionData["object"],
SIGNAL(connectionData["signal"]),
self.hackedDisplayArea.update)
Nota - El self.endAngle etc. se inicializan en el constructor
Hasta donde yo sé, las razones para elegir un dict son para una búsqueda rápida. ¿Cuándo está eso garantizado? cuando tengo 100 cajas o más? ¿Es una buena idea seguir creando y tirando un diccionario cada vez que se llame a la función? Si construyo un dict para este propósito fuera de una función, ¿debería verificar si se necesita en otro lugar? ¿Qué pasa si no es necesario en otro lado?
Mi pregunta es ¿cuál es la mejor práctica si hay una? ¿Cuál es la mejor/más elegante forma de hacer las cosas? Dicho de otra manera, ¿cuándo usar if-elif-else, cuándo usar cada una de las otras opciones?
Si utilizo una clave estática simple para valorar el mapeo, sigue siendo una mala idea construir sobre la marcha ¿no? En ese caso, ¿no tendría que usar if-else, a menos que almacenara el diccionario en alguna parte y lo usara en dos o más lugares? Gracias por la respuesta detallada. – batbrat
Solo para estar seguro, no debería hacer algo como {key1: function1, key2: function2} .get (..., ...) ¿no? – batbrat
Construir un diccionario sobre la marcha no es lo que ** significa **. Si quieres decir if-elif-elif, solo di eso. Si su ** significado ** es "Esta clave siempre se asigna a esta función", dígala como parte oficial de primera clase de su programa. –