Ответ 1
import module
class ReplaceClass(object):
....
module.MyClass = ReplaceClass
У меня есть класс, расположенный в отдельном модуле, который я не могу изменить.
from module import MyClass
class ReplaceClass(object)
...
MyClass = ReplaceClass
Это не изменяет MyClass нигде, кроме этого файла. Однако, если я добавлю метод, подобный этому
def bar():
print 123
MyClass.foo = bar
это будет работать, и метод foo будет доступен везде.
Как полностью заменить класс?
import module
class ReplaceClass(object):
....
module.MyClass = ReplaceClass
Избегайте from ... import
(ужасный;-) способ получить имена, если вам больше всего нужны квалифицированные имена. Когда вы делаете что-то правильно, питоновский путь:
import module
class ReplaceClass(object): ...
module.MyClass = ReplaceClass
Таким образом вы можете обезвредить объект module, который вам нужен и будет работать, когда этот модуль будет использоваться для других. С формой from ...
у вас просто нет объекта модуля (один из способов взглянуть на вопиющий дефект большинства людей, использующих from ...
), и поэтому вам явно хуже: -);
Единственный способ, которым я рекомендую использовать оператор from
, - это импортировать модуль из пакета:
from some.package.here import amodule
так что вы все еще получаете объект модуля и будете использовать квалифицированные имена для всех имен в этом модуле.
Я всего лишь яйцо.,, Возможно, это очевидно для не-новичков, но мне нужна идиома from some.package.module import module
.
Мне пришлось изменить один метод GenerallyHelpfulClass. Это не удалось:
import some.package.module
class SpeciallyHelpfulClass(some.package.module.GenerallyHelpfulClass):
def general_method(self):...
some.package.module.GenerallyHelpfulClass = SpeciallyHelpfulClass
Код работал, но не использовал поведение, перегруженное на SpeciallyHelpfulClass.
Это сработало:
from some.package import module
class SpeciallyHelpfulClass(module.GenerallyHelpfulClass):
def general_method(self):...
module.GenerallyHelpfulClass = SpeciallyHelpfulClass
Я предполагаю, что from ... import
idiom 'получает модуль', как писал Алекс, поскольку он будет подхвачен другими модулями в пакете. Далее, более длинная пунктирная ссылка, по-видимому, приводит модуль в пространство имен с импортом по длинной пунктирной ссылке, но не изменяет модуль, используемый другими пространствами имен. Таким образом, изменения в модуле импорта будут отображаться только в пространстве имен, где они были сделаны. Это как если бы имелись две копии одного и того же модуля, каждая из которых была доступна под несколько разных ссылок.
import some_module_name
class MyClass(object):
... #copy/paste source class and update/add your logic
some_module_name.MyClass = MyClass
Предпочтительно не менять имя класса при замене, потому что каким-то образом кто-то может ссылаться на них с помощью getattr - что приведет к сбою, как показано ниже
getattr(some_module_name, 'MyClass')
→ , который сработает, если вы заменили MyClass на ReplaceClass!