我将尝试简化这里的情况,当覆盖__new__如下时,我不知道调用 super__new__来完成这项工作的正确方法,我做得好吗还是有其他方法可以做到这一点?
super().__new__(cls)没有产生我预期的正确结果
我是 python 初学者,请耐心等待,我很流利 C++
import weakref
class A(str):
def __init__(self,s):self.a=s
class B(str):
def __init__(self,s):self.b=s
class P(A,B):
manifest=weakref.WeakValueDictionary()
def __new__(cls,a,b):
o=P.manifest.get(a+b)
if not o:
print(a,b,super(P,cls))
#i thought this first should be used because __init__ puts the values in
#and we index the manifest with parameters [a+b]
#o=super().__new__(cls)#produces unique results for all requests?!?
#so i called like this and it works (either with a or b)
o=super().__new__(cls,a)#why favoring a over b?
#o=super().__new__(cls,b)#why favoring b over a?
#o=super().__new__(cls,a,b)#its an error (of coz)
P.manifest[a+b]=o
print("using",id(o))
return o
def __init__(self,a,b):
A.__init__(self,a)
B.__init__(self,b)
p=P("a","b")
q=P("a","b")
r=P("a","x")
print(id(p),id(q),id(r))
Run Code Online (Sandbox Code Playgroud)
我怀疑(但我不确定)您正在尝试调用__new__您的两个超级类,即A和B。做到这一点的最佳方法取决于很多因素。
的目的P.__new__是返回 的实例P。这就是你应该创建的。这确实是super().__new__(cls,a)可行的,所以应该可以正常工作,但是,您也可以str.__new__(cls, a)直接调用。
通常你实际上会调用object.__new__,但由于你str不能这样做,所以它会告诉你在这种情况下它是不安全的。
如果您确实想使用super()(并且在某些情况下这是一个好主意),您通常应该在所有类中一致地使用它,因此它也应该在A和中使用B,不仅在,__new__而且在__init__
class A(str):
def __init__(self, s):
super().__init__(s)
self.a = s
def __new__(cls, s):
return super().__new__(cls, s)
class B(str):
def __init__(self, s):
super().__init__(s)
self.b = s
def __new__(cls, s):
return super().__new__(cls, s)
Run Code Online (Sandbox Code Playgroud)
然而,这在这里变得有问题,因为你没有相同的函数配置文件,因为 P 需要两个参数。这可以表明您的解决方案可能不是最好的解决方案。特别是因为 P 是一个以两个字符串作为参数的字符串,所以这没有多大意义。在上一个问题中,您谈到了多态性,这是一种在某种程度上打破了多态性的模式,因为 P 没有与 A 和 B 相同的 API,因此不能互换使用。
结果是我怀疑子类化在这里是错误的解决方案。另外,我猜测您正在尝试缓存对象,以便使用相同参数创建新对象实际上会返回相同的对象。我建议您使用工厂方法,而不是重写__new__.
| 归档时间: |
|
| 查看次数: |
3833 次 |
| 最近记录: |