Lo que quiere hacer es llamar "parche de monos", y tiene poco que ver con la orientación de objetos.
Python lo admite, pero usted tiene el control de todas sus clases, debe revisar seriamente su proyecto para comprobar si realmente lo necesita.
Quizás usando un marco como Zope Component Architecture, que le permite marcar clases con interfaces, y proporciona objetos de adaptador para que pueda usar limpiamente un objeto como si tuviera alguna interfaz que no estaba diseñada para tener en primer lugar, será una mejor idea
Dicho esto, lo que está pidiendo es cambiar la clase, en el otro módulo, donde está, para que los cambios sean visibles para todos los demás módulos.
Hace exactamente eso: cambie la clase en el módulo al que pertenece. En Python se puede hacer simplemente atribuyendo su nueva clase al nombre deseado, en el módulo de origen:
import base_classes
class Bookcollection(base_classes.Bookcollection):
new_member = "lalala"
base_classes.Bookcollection = Bookcollection
(Se recomienda encarecidamente evitar "de x import *" en cualquier proyecto más grande que la única secuencia de comandos - en este caso, tenía 2 variables con el mismo nombre y diferentes significados en todo su código: la clase base y la clase heredada, por ejemplo. Los espacios de nombres de Python le permiten evitar eso).
Por lo tanto, esto cambiará la clase Bookcollection en el módulo base_class - PERO solo para el código que lo hará referencia desde este punto y en su cadena de ejecución. Si la clase "x" en su ejemplo, se define en el módulo "base_classes", o se define antes de que se importe "MyModule", obtendrá una referencia a la antigua clase "Bookcollection".
Como puede ver, puede convertirse rápidamente en un desastre, y si realmente elige este enfoque, la única manera de mantener su proyecto incluso utilizable, es tener pruebas de unidad para verificar que todas las clases que desea reparar, en realidad están parcheados Incluso el orden de importación de los módulos marcará la diferencia, como puede ver. Si tiene lugar en las pruebas, se romperán si realiza las importaciones en un orden que rompa el parche de su mono.
Si solo necesita agregar y reemplazar cosas en una clase existente, puede parchear mono la clase para reemplazar sus componentes, en lugar de parchear el módulo en el que se encuentra para reemplazar la clase. De esta manera, el orden de importación de módulos no importa mucho - que afectará incluso a las instancias existentes de esa clase:
import base_classes
base_classes.Bookcollection.new_member = "lalala"
def new_bookcol_method(self):
pass
# to replace or register a method in the other class:
base_classes.Bookcollection.__dict__["old_bookcol_method"] = new_bookcol_method
Esto le dará un comportamiento más consistente que intentar asignar una nueva clase (que es un objeto en sí mismo) al mismo nombre en el módulo original.
En general, debe hacer como @jamesj sugiere en su respuesta, y usar clases distintas, o si necesita el comportamiento dinámico, use un marco de mantenimiento para eso, como Zope Component Architecture. Y cualquiera que sea el enfoque que tome, haga pruebas de unidades de escritura.
si se enreda en cadenas de herencia, entonces tal vez debería buscar otras soluciones. – jldupont
¡¿Tal vez podría intentar trabajar con ganchos ?! –