poo - metodos en python
Clase Python de parche de mono (4)
Tengo una clase, ubicada en un módulo separado, que no puedo cambiar.
from module import MyClass
class ReplaceClass(object)
...
MyClass = ReplaceClass
Esto no cambia MyClass en ningún otro lugar, pero este archivo. Sin embargo si agrego un método como este
def bar():
print 123
MyClass.foo = bar
Esto funcionará y el método Foo estará disponible en cualquier otro lugar.
¿Cómo reemplazo la clase completamente?
Evite la forma from ... import
(horrible ;-) para obtener nombres de barras cuando lo que más necesita son nombres calificados . Una vez que haces las cosas de la manera correcta de Pythonic:
import module
class ReplaceClass(object): ...
module.MyClass = ReplaceClass
De esta manera, estás parcheando el objeto del módulo , que es lo que necesitas y funcionará cuando ese módulo se use para otros. Con la forma from ...
, simplemente no tiene el objeto de módulo (una forma de ver el defecto evidente del uso de la mayoría de la gente por parte de from ...
) y por lo tanto, obviamente está peor ;-);
La única forma en que recomiendo usar la declaración from
es importar un módulo desde un paquete:
from some.package.here import amodule
por lo que aún está recibiendo el objeto de módulo y utilizará nombres calificados para todos los nombres en ese módulo.
No soy más que un huevo. . . . Tal vez sea obvio para los no novatos, pero necesitaba el from some.package.module import module
.
Tuve que modificar un método de la clase Generalmente Helpful. Esto falló:
import some.package.module
class SpeciallyHelpfulClass(some.package.module.GenerallyHelpfulClass):
def general_method(self):...
some.package.module.GenerallyHelpfulClass = SpeciallyHelpfulClass
El código se ejecutó, pero no utilizó los comportamientos sobrecargados en SpeciallyHelpfulClass.
Esto funcionó:
from some.package import module
class SpeciallyHelpfulClass(module.GenerallyHelpfulClass):
def general_method(self):...
module.GenerallyHelpfulClass = SpeciallyHelpfulClass
Especulo que el idioma from ... import
''recibe el módulo'', como escribió Alex, ya que será recogido por otros módulos en el paquete. Al especular aún más, la referencia punteada más larga parece llevar el módulo al espacio de nombres con la importación por referencia punteada larga, pero no cambia el módulo utilizado por otros espacios de nombres. Por lo tanto, los cambios en el módulo de importación solo aparecerían en el espacio de nombres donde se realizaron. Es como si hubiera dos copias del mismo módulo, cada una disponible con referencias ligeramente diferentes.
import module
class ReplaceClass(object):
....
module.MyClass = ReplaceClass
import some_module_name
class MyClass(object):
... #copy/paste source class and update/add your logic
some_module_name.MyClass = MyClass
Es preferible no cambiar el nombre de la clase mientras se reemplaza, porque de alguna manera alguien puede haberlos mencionado usando getattr, lo que resultará en un fallo como el que se muestra a continuación
getattr(some_module_name, ''MyClass'')
-> que fallará si has reemplazado MyClass por ReplaceClass!