variable stringvar python class python-3.x

variable - stringvar tkinter python 3



Cambiar el tipo de clase de una clase después de los datos insertados (3)

¿Por qué no usar un método de fábrica? Éste decidirá qué clase instanciar dependiendo de los datos pasados. Usando tu ejemplo:

def create_number(number): if number < 1000: return SmallNumber(number) return BigNumber(number)

Quiero crear una clase en python, que debería funcionar así:

  1. Datos asignados, tal vez vinculados a una variable (por ejemplo, a = exampleclass(data) o simplemente exampleclass(data) )

  2. Al ser insertados datos, debe determinar automáticamente algunas propiedades de los datos, y si se cumplen algunas propiedades, automáticamente ...

  3. ... cambiar de clase a otra clase

La parte 3 es la parte con la que tengo un problema. ¿Cómo cambio realmente la clase dentro de la clase? por ejemplo:

Si tengo dos clases, una es Small_Numbers , y la otra es Big_numbers ; ahora quiero que cualquier small_number menor de 1000 se transfiera a Big_number y viceversa, testcode:

a = Small_number(50) type(a) # should return Small_number. b = Small_number(234234) type(b) # should return Big_number. c = Big_number(2) type(c) # should return Small_number.

¿Es posible hacer esto?


No lo hagas Use una función de fábrica en su lugar.

def create_number(source): if source < 1000: return Small_number(source) else: return Big_number(source) a = create_number(50) b = create_number(234234) c = create_number(2)


Usar un método de fábrica es la forma habitual de resolver esto, especialmente dado que la creación de instancias de una clase no se puede distinguir de llamar a una función en Python.

Sin embargo, si realmente quieres, puedes self.__class__ a self.__class__ :

THRESHOLD = 1000 class Small(object): def __init__(self, n): if n < THRESHOLD: self.n = n else: self.__class__ = Big self.__init__(n) class Big(object): def __init__(self, n): if n < THRESHOLD: self.__class__ = Small self.__init__(n) else: self.n = n

Esto funciona como se esperaba:

>>> a = Small(100) >>> type(a) <class ''Small''> >>> b = Small(1234) >>> type(b) <class ''Big''> >>> c = Big(2) >>> type(c) <class ''Small''>

Si asignar a self.__class__ parece demasiado extraño, entonces puede anular __new__ en __new__ lugar. Este método se llama antes de llamar a __init__ y se puede usar para elegir la clase para instanciar:

THRESHOLD = 1000 class Switcher(object): def __new__(cls, n): if n < THRESHOLD: new_cls = Small else: new_cls = Big instance = super(Switcher, new_cls).__new__(new_cls, n) if new_cls != cls: instance.__init__(n) return instance class Small(Switcher): def __init__(self, n): self.n = n class Big(Switcher): def __init__(self, n): self.n = n