Что вы хотите сделать, называется «обезглавливание обезьян» и имеет мало общего с Ориентацией объектов.
Python действительно поддерживает его, но у вас есть контроль над всеми вашими классами, вы должны серьезно рассмотреть свой проект, чтобы проверить, действительно ли вам это нужно.
Возможно, используя инфраструктуру, такую как Zope Component Architecture, которая позволяет вам маркировать классы с интерфейсами и предоставляет объекты адаптера, чтобы вы могли чисто использовать один объект с некоторым интерфейсом, на котором он не был создан на первом месте, будет лучшая идея.
Таким образом, то, о чем вы просите, это изменить класс в другом модуле, где он есть, - чтобы изменения были видны для всех других модулей.
Вы делаете именно это: измените класс в модуле, в котором он находится. В Python это может быть сделано просто приписывать свой новый класс к нужному имени в модуле происхождения:
import base_classes
class Bookcollection(base_classes.Bookcollection):
new_member = "lalala"
base_classes.Bookcollection = Bookcollection
(настоятельно рекомендуются, чтобы избежать «от й импорта *» в любом проекте больше, чем один скрипт - в этом случае у вас было 2 переменные с одинаковым именем и разные значения во всем коде: базовый класс и унаследованный класс, например. Пространства имен Python позволяют избежать этого).
Таким образом, это изменит класс Bookcollection в модуле base_class - НО только для кода, который будет ссылаться на него с этой точки и на вашей цепочке выполнения. Если класс «x» в вашем примере определен в модуле «base_classes» или иначе определен до импорта «MyModule», он получит ссылку на старый класс «Bookcollection».
Как вы можете видеть, он может быстро стать беспорядком, и если вы действительно выбираете этот подход, единственный способ сохранить ваш проект даже в использовании, - это иметь модульные тесты для проверки того, что все классы, которые вы хотите запланировать, фактически исправлены. Как вы видите, даже импортный порядок модулей будет иметь значение. Если у вас есть тесты, они сломаются, если вы сделаете импорт в порядке, который нарушит вашу патчу обезьяны.
Если вам просто нужно добавить и заменить вещи в существующем классе, вы можете обезвредить сам класс, чтобы заменить его компоненты, вместо того, чтобы обезвреживать модуль, он должен заменить класс. Таким образом, порядок импорта модулей не имеет большого значения - это повлияет даже существующие экземпляры этого класса:
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
Это даст вам более последовательное поведение, чем пытаться назначить новый класс (который объект сам по себе) с тем же именем в исходном модуле.
В целом, вы должны либо делать, как @jamesj предлагает в своем ответе, и использовать разные классы, или если вам нужно динамическое поведение, используйте для этого поддерживаемую инфраструктуру, такую как Zope Component Architecture. И независимо от того, какой подход вы принимаете, do пишите модульные тесты.
Если вы запутались в цепях наследования, то, возможно, вам стоит взглянуть на некоторые другие решения. – jldupont
Возможно, я мог бы попытаться работать с крючками ?! –