我有一个父类,所以我想做一个父类,以便可以从类工厂返回它的子类,这是一些代码:
class Super:
def __new__(cls, t):
return class_factory(t)
# Because I need a Super class with some custom state
def class_factory(t):
class Sub(Super):
t = t
def __init__(self):
pass
return Sub
assert isinstance(Super(1)(), Super)
我收到以下错误:
TypeError: __new__() missing 1 required positional argument: 't'
我知道它试图调用Super
的{{1}}方法。有没有一种方法可以跳过它,或者至少以不引起无限递归的方式保留类型签名? (我需要保留两个类的类型签名)。
答案 0 :(得分:1)
当我运行您的代码时,出现另一个错误,即:
cvxpy
在numpy
行上。
这是因为NameError: name 't' is not defined
语句的主体是在其自己的名称空间中执行的,因此封闭名称空间中的t = t
不在正常范围内。另一个问题是您的class
没有调用其基类't
。
最后,对__new__()
的调用是错误的。调用类将返回该类的实例(在本例中为子类的实例)。
要解决所有这些问题并使代码正常工作,您可能需要这样做:
__new__()
更新:
根据您的评论,我建议改用类装饰器。 —像这样:
Super(1)()
这不会创建子类,但是您可以根据需要更改修饰类的名称。
答案 1 :(得分:0)
这可能有效:
class Super:
def __new__(cls, t):
return class_factory(t)
def class_factory(t):
class Sub(Super):
_tp = t
def __new__(cls, *args, **kwargs):
instance = object.__new__(cls)
return instance
def __init__(self, *args, **kwargs):
pass
return Sub
为避免错误,您需要在__new__()
中定义自定义Sub
方法,因此可以避免递归调用Super
的{{1}}方法。
该类型保留在__ new__()
的{{1}}类属性中。
使用此代码,_tp
不会引发任何错误。
修复了Sub
和assert isinstance(Super(1)(), Super)
。规则是*args
也必须使用**kwargs
中使用的任何参数签名。例如,如果您需要Sub.__init__()
,那么您应该拥有Sub.__new__()
。