覆盖父类中使用过的类 [英] Override used classes in parent class
问题描述
假设在我无法编辑的地方有一个使用其他类LesserClass
的类NiceClass
# NiceClass.py
class LesserClass:
...
# stuff
...
class NiceClass:
...
# Lots of use of lesser class in here...
...
现在,我想在继承的NiceClass
MyLesserClass
而不是LesserClass
# MyNiceClass.py
from NiceClass import NiceClass
from NiceClass import LesserClass as oldLesserClass
class LesserClass(oldLesserClass):
...
# Some extra stuff
...
class MyNiceClass(NiceClass):
...
# Everywhere LesserClass was used I now want to use MyLesserClass
...
但是MyNiceClass
中所有不可重写的方法都将使用旧版NiceClass.py
中的LesserClass
.
如果我只是将NiceClass
的整个定义复制粘贴到MyNiceClass.py
,一切都会按我的意愿进行.
这就像我只想继承源代码,而不是整个命名空间一样.也许继承是错误的方式?
我希望这仅限于使用LesserClass
类的NiceClass
下的方法.
现在,如果您希望MyNiceClass
中的方法使用MyLesserClass
而不是LesserClass
,则可以更新这些方法的__globals__
格,并将名称'LesserClass'
指向MyLesserClass
.>
这是一个简单的示例,它通过覆盖 __getattribute__
:
class A:
a = 'A.a'
b = 'A.b'
class B:
def func_a(self):
print(A.a)
def func_b(self):
print(A.b)
class C:
a = 'C.a'
b = 'C.b'
class D(B):
def func_a(self):
print(C.a)
def __getattribute__(self, attr):
value = object.__getattribute__(self, attr)
if callable(value):
value = update_namespace(value, {'old': {'name': 'A', 'obj': A}, 'new': {'obj': C}})
return value
def update_namespace(func, namespace):
def wrapper(*args, **kwargs):
# Update the globals
func.__globals__[namespace['old']['name']] = namespace['new']['obj']
val = func(*args, **kwargs)
# Restore it back to the actual value
func.__globals__[namespace['old']['name']] = namespace['old']['obj']
return val
return wrapper
d = D()
d.func_a() # This should print C.a
d.func_b() # This should print C.b
输出:
C.a
C.b
Suppose there is a class NiceClass
using some other class LesserClass
in a place I can't edit
# NiceClass.py
class LesserClass:
...
# stuff
...
class NiceClass:
...
# Lots of use of lesser class in here...
...
Now I want to use my own class MyLesserClass
instead of LesserClass
everywhere in an inherited version of NiceClass
# MyNiceClass.py
from NiceClass import NiceClass
from NiceClass import LesserClass as oldLesserClass
class LesserClass(oldLesserClass):
...
# Some extra stuff
...
class MyNiceClass(NiceClass):
...
# Everywhere LesserClass was used I now want to use MyLesserClass
...
But all the non-overridden methods in MyNiceClass
will use the LesserClass
from the old NiceClass.py
.
Everything would work as I want if I just copy-pasted in the whole definition of NiceClass
into MyNiceClass.py
.
It's like I just want to inherit the source code and not the whole namespace. Maybe inheritence is the wrong way?
I hope this is only limited to methods under NiceClass
using the class LesserClass
.
Now if you want the methods inside MyNiceClass
to use MyLesserClass
instead of LesserClass
then you could update the __globals__
dict of those methods and make the name 'LesserClass'
point to MyLesserClass
.
Here's a simple example demonstrating the same by overriding __getattribute__
:
class A:
a = 'A.a'
b = 'A.b'
class B:
def func_a(self):
print(A.a)
def func_b(self):
print(A.b)
class C:
a = 'C.a'
b = 'C.b'
class D(B):
def func_a(self):
print(C.a)
def __getattribute__(self, attr):
value = object.__getattribute__(self, attr)
if callable(value):
value = update_namespace(value, {'old': {'name': 'A', 'obj': A}, 'new': {'obj': C}})
return value
def update_namespace(func, namespace):
def wrapper(*args, **kwargs):
# Update the globals
func.__globals__[namespace['old']['name']] = namespace['new']['obj']
val = func(*args, **kwargs)
# Restore it back to the actual value
func.__globals__[namespace['old']['name']] = namespace['old']['obj']
return val
return wrapper
d = D()
d.func_a() # This should print C.a
d.func_b() # This should print C.b
Output:
C.a
C.b
这篇关于覆盖父类中使用过的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!