2010-09-16 27 views
7

Desde el tutorial: "Una definición de clase es una instrucción ejecutable".Creación de clase condicional (Python)

¿Se recomienda lo siguiente en un script?

my_switch = False 
if my_switch: 
    class Hello: 
     def __init__(self): 
      self.greeting = "Hello!" 

else: 
    class Hello: 
     def __init__(self): 
      self.greeting = "Salut!" 
+0

Lo siento, quise preguntar si era una práctica recomendada. Pregunta actualizada – ash

+1

Para casos más complejos, la práctica recomendada sería [metaclases] (http://www.ibm.com/developerworks/linux/library/l-pymeta.html), para que no se repita. –

+1

BTW, para el caso específico de localización, recomendaría el módulo 'gettext' en la biblioteca estándar. Utilizándolo, su ejemplo podría ser manejado por una única clase con 'self.greeting = _ (" Hello ")' en él. – martineau

Respuesta

9

incluso se puede hacer

class Hello: 
    def __init__(self): 
     self.greeting = "Hello!" 

class Salut: 
    def __init__(self): 
     self.greeting = "Salut!" 

if my_switch: 
    Hello = Salut 

(tenga en cuenta que el código necesita minúsculas clase palabras clave ...)

+0

Gracias, actualicé mi código. ¡Esto es algo genial! – ash

+0

-1 @Jasie Esto está mal por tres razones: 1) ¿por qué definir una clase si no vas a usarla? 2) como originalmente la tenías, estaba claro que el identificador 'Hello' podría referirse a uno de dos objetos de clase diferentes __ en el tiempo de creación__. Ahora, necesito leer más adelante en el código para ver esto, ya que no es del todo obvio 3) cualquier depuración realizada con 'my_switch == True' generará' Salut' como el nombre de la clase. Esto será confuso para otras personas. – aaronasterling

+0

Prefiero decir que como un ejemplo que demuestra que las clases son objetos de primera clase también en P ython, no como un código real para usar. Por supuesto, para cosas como traducciones vas a usar gettext o algo similar de todos modos. –

5

Sí, el código es válido. pero ¿por qué no simplemente ejecutar el código para averiguarlo?

También puede hacer esto con las definiciones de funciones.

+1

Su primera declaración es un poco dudosa. Si toma este enfoque en general, encontrará que, en C, por ejemplo, los cambios negativos a menudo parecen hacer algo que podría ser útil, pero si en su lugar lee el manual C encontrará que el idioma en realidad no es compatible con esto. . Estoy de acuerdo en que "pruébalo y ve" es muy útil en Python, pero definitivamente puedo ver el valor de preguntar: "Parece que esto funciona, pero ¿es * recomendado *? ¿Es probable que falle en futuras versiones de python? , o en otras plataformas? u otros problemas? En este caso, la respuesta es no, pero aún así. – greggo

3

Es un código válido, pero realmente no se recomienda en ese formato (suponiendo que el código sería sigue la declaración de clase). Dado que eventualmente usarás la clase. Suponiendo que aún utilizas dos clases con el mismo nombre, puede ser confuso después. Tal vez deberías tener el código envuelto en una función para devolver la clase que has creado. Ahora tiene un factory básico.

def HelloFactory(my_switch) 
    if my_switch: 
     class Hello: 
      def __init__(self): 
       self.greeting = "Hello!" 
    else: 
     class Hello: 
      def __init__(self): 
       self.greeting = "Salut!" 
    return Hello 

helloClass = HelloFactory(False) 
hello = helloClass() 
hello.greeting 

Producir "Salut!"

+0

siento este fragmento aún más complicado que el de OP. Creo que se debe evitar el uso de clases/funciones anidadas, ya que realmente disminuye la legibilidad del código. – MatToufoutu

+0

@MatToufoutu No pretendía ser un reemplazo, sino un simple ejemplo de que podría crear métodos de fábrica. Estoy de acuerdo en que agregar código con el fin de agregar código creará legibilidad del código. – Rod

4

Sin duda no se recomienda para la localización, como en su ejemplo.

Lo principal a tener en cuenta es cuánto del código va a ser similar versus diferente en las versiones especializadas de la clase. Si solo una pequeña cantidad de código es diferente, o si solo los datos son diferentes ("Hola" frente a "Salut"), existen formas mejores.

Un caso en el que podría considerar la declaración de clases condicional es si proporciono funcionalidad en dos sistemas operativos diferentes, y obtener esa funcionalidad es muy diferente entre los dos. Como ejemplo, tal vez estoy tratando de conducir iTunes desde un script, y en MacOS estoy usando AppleScript para conducirlo, pero en Windows tengo que usar COM. Podría crear una clase contenedora que el resto de mi código podría usar sin importar qué SO estaba en uso.

+1

Incluso en su caso OS no lo haría así. Tendría una clase para padres que es un 'abc'. Los niños serían específicos del sistema operativo. El '' __new__' del padre devolvería un objeto del tipo específico del SO apropiado. – Daenyth

0

Es posible que no necesite repetir el código como lo hace. Pregúntese si necesita repetir el código de construcción de la clase, o solo las variables dentro de la misma clase? Si es esto último, entonces se podría usar la misma clase para ambos casos utilizando un argumento en __init__(), y luego condicionalmente devolver una instancia de la clase con la variable deseada:

my_switch = False 

class Hello: 
    def __init__(self, greeting): 
     self.greeting = greeting 

if my_switch: 
    mygreeting = "Hello!" 
else: 
    mygreeting = "Salut!" 

hello = Hello(mygreeting) 
print hello.greeting 
# => Salut! 
4

También se puede poner condiciones en torno al " declaraciones" dentro de la clase, ya que estos se ejecutan como parte de la construcción de clase:

class Hello: 
    if my_switch: 
     igreeting = "Hello!" 
    else: 
     igreeting = "Salut!"  
    def __init__(self, greeting): 
      self.greeting = self.igreeting 

(igreeting que aquí hay una variable de clase, saludando a una variable miembro)

o simplemente

class Hello: 
    if my_switch: 
     greeting = "Hello!" 
    else: 
     greeting = "Salut!"  

... generalmente dará el mismo efecto.

5

Si te gusta más, puedes poner cada definición de clase en un archivo .py separado y solo import el que quieras.Algo como lo siguiente:

if my_switch: 
    from hello_en import Hello 
else: 
    from hello_fr import Hello 

h = Hello() 
Cuestiones relacionadas