将这个问题和相关问题的答案放在一起,我想强调一下这个问题的解决方案:
您可以通过创建具有相同名称的子类然后用其子类替换父类来进行修改。__slots__
请注意,您可以对任何模块中声明和使用的类执行此操作,而不仅仅是您的!
考虑以下声明一些类的模块:
module.py:
class A(object):
# some class a user should import
__slots__ = ('x', 'b')
def __init__(self):
self.b = B()
class B(object):
# let's suppose we can't use it directly,
# it's returned as a part of another class
__slots__ = ('z',)
以下是向这些类添加属性的方法:
>>> import module
>>> from module import A
>>>
>>> # for classes imported into your module:
>>> A = type('A', (A,), {'__slots__': ('foo',)})
>>> # for classes which will be instantiated by the `module` itself:
>>> module.B = type('B', (module.B,), {'__slots__': ('bar',)})
>>>
>>> a = A()
>>> a.x = 1
>>> a.foo = 2
>>>
>>> b = a.b
>>> b.z = 3
>>> b.bar = 4
>>>
但是,如果您使用module
.
module_3rd_party.py:
from module import A
def get_instance():
return A()
没问题,它也会起作用!唯一的区别是您可能需要在导入第三方模块之前module
修补它们(以防它从 导入类):
>>> import module
>>>
>>> module.A = type('A', (module.A,), {'__slots__': ('foo',)})
>>> module.B = type('B', (module.B,), {'__slots__': ('bar',)})
>>>
>>> # note that we import `module_3rd_party` AFTER we patch the `module`
>>> from module_3rd_party import get_instance
>>>
>>> a = get_instance()
>>> a.x = 1
>>> a.foo = 2
>>>
>>> b = a.b
>>> b.z = 3
>>> b.bar = 4
>>>
它之所以有效,是因为 Python 只导入一次模块,然后在所有其他模块之间共享它们,因此您对模块所做的更改会影响您运行的所有代码。