【发布时间】:2020-10-05 07:37:42
【问题描述】:
我的设置:我在 windows10 机器上使用 spyder4 编写 python 3.7。
上下文
我正在为一个包编写类。它是我正在导入的另一个包中定义的类的某种处理程序。
这里是情况的简化版本:
# This I cannot modify, as they are in the package
class Letter_Class():
def __init__(self, name):
self.name = name
class A(Letter_Class):
def source(self):
print("from class A")
def funcA(self):
print("from class A")
class B(Letter_Class):
def source(self):
print("from class B")
def funcB(self):
print("from class B")
class C(Letter_Class):
def source(self):
print("from class C")
def funcC(self):
print("from class C")
# This I can modify
class Dynamic(Letter_Class):
def __new__(self, name, this_class): # -------- issue lies here? --------
obj = this_class(name)
return obj
def new_func(self):
print("function defined in dynamic class")
Letter_Class、A、B、C 类已经由其他人定义(在我正在处理的“其他包”中),我无法更改它们。我想创建一个类,这里称为“Dynamic”,它将从作为参数给出的类继承。它必须仍然具有我希望添加的(很多很多)方法,例如new_func()。我无法提前知道使用了哪个Letter_Class child。
类A、B、C既有多态方法又有特定方法,例如source()和funcA()。因此,我不能让Dynamic 从这些类继承。这太容易了。
问题
如果我执行前面和下面的代码:
# user executes in main:
instance = Dynamic("test name", B)
print(instance.name)
instance.source()
instance.funcB()
instance.new_func()
我明白了:
test name
from class B
from class B
AttributeError: 'B' object has no attribute 'new_func'
实例创建完成,source() 和 funcB() 执行没有任何问题。
然后,引发属性错误,因为没有真正创建 Device 对象。
谁能向我解释在__new__() 构造函数中放入什么来实际返回Device 类的实例,并从this_class 正确继承?我将不胜感激。
This discusion 似乎解决了这个问题,但在不同的情况下,我无法应用建议的解决方案。
【问题讨论】:
-
" 我想创建一个类,这里称为 "Dynamic",它将从作为参数给出的类继承。"这没有多大意义。继承发生在定义类时而不是创建实例时。可能有一些 hacky 方法可以完成此操作,但您几乎肯定不应该这样做。很可能,您只需要某种代理类。
-
所以,这是一个very similar question,我在其中给出了一个答案,演示了如何定义代理类。
-
@juanpa.arrivillaga 感谢您的链接。我想出了一个像你这样的解决方案,通过将调用重定向到我想要包装的类的私有变量。我缺少
__getattr__()特殊方法,这完美地解决了问题。代理类正是我正在寻找的,我会看看我是否可以在我的项目中实现它。非常感谢 -
请注意,这样的代理不适用于 dunder 方法,例如
__eq__或__str__。通常这很好...here's 一种解决方法,如果不是,我准备了一些其他答案,如果这对您来说是个问题...
标签: python class oop inheritance arguments