我必须关注模块:
class A():
a = 1
class B(A):
b = 2
在另一个文件中,我想替换A类(like here):
import module
class C():
c = 3
module.A = C
创建B
对象时,它应该立即从C
继承,并且具有.c
属性,但是,它不会:
assert module.B().c == 3
但是,这会引发:AttributeError: 'B' object has no attribute 'c'
如何解决这个问题?
答案 0 :(得分:1)
变量是对象的引用。重新分配变量时,它不会影响前一个对象,除非它的引用计数变为零并且它被删除。在你的情况下
class A:
a = 1
class B(A):
b = 2
B
获取当时恰好分配给A
的类对象,并将其用作父对象。只要B
将super
用于将来对其父级的引用,B
就不会再次触及A
变量。你对A
的重新分配没有任何区别。
但你确实说过Monkey Patch,这仍然可行。只需将东西放到原来的A类上,所有的继承者都会看到它:
import module
module.A.c = 3
assert module.B().c == 3
您还可以添加或替换方法
import module
def d(self):
return 4
module.A.d = d
assert module.B().d() == 4
或者,如果您只想对某些 A的继承者进行此更改,请考虑使用mixins What is a mixin, and why are they useful?
答案 1 :(得分:0)
post of tdelaney中的想法可以自动化:
def replace_class(oldcls, newcls):
'''Adds/replaces the contents for oldcls with newcls, leaving
references to oldcls in-place. Usefull for monkey patching'''
for key, val in newcls.__dict__.items():
if key != '__dict__':
setattr(oldcls, key, val)
现在可行了
replace_class(module.A, C)
module.B().c == 2