【发布时间】:2020-12-05 07:11:53
【问题描述】:
我试图找出一种方法来创建预先确定的列表,以避免列表对象的限制,例如无法插入到列表末尾之外。所以这段代码按照我想要的方式构建列表,但是直到我开始实现 __str__() 方法时我才注意到这个 to string 方法实际上从未被调用过。
似乎是这个类正在创建list,而不是它被调用和定义的ArrayList。我的ArrayList 班级去哪儿了?所以,为了从课堂上调用__str__(),我必须暴力破解它,这确实违背了目的,而且我还想在混合中添加其他不会直接调用的方法,我敢肯定。
所以,我想知道是否可以采取一些措施来解决此问题,或者可能有更好的方法。我也不打算使用另一个现有的类,例如用于数组。在这一点上,这是教学法,我希望继续朝着同样的方向前进。这是我的代码:
import copy
class ArrayList(list):
def __init__(self, *dim, initial = []):
pass
def __new__(cls, *dim, initial=[]):
template = None
for d in range(len(dim)-1, -1, -1):
if template is None:
template = [initial for _ in range(dim[d])]
else:
template = [copy.deepcopy(template) for _ in range(dim[d])]
return template
def __str__(self):
print('using override')
print(len(self))
for i in range(len(self)):
print(self[i])
return
var1 = ArrayList(4,3,2,initial=0)
print(var1)
print(type(var1)) # <class 'list'>
print(var1 is ArrayList) #False
print(ArrayList.__str__(var1))
# var2 = ArrayList(3,2,2,initial='a')
# var2[1][0][1] = 5
# print(var2)
# print("~"*20)
# var1[2][2] = 17
# print(*var1, sep='\n')
# print(len(var1))
# print("~"*20)
# print(ArrayList.__str__(var1)) #this works
【问题讨论】:
-
“返回的对象应该是类的类型” - 如你应该让它成为那个类型,通常通过调用
super.__new__(yourclass, ...)。它不会接受你返回的任何东西并以某种方式改变它的类型。 (从技术上讲,您也可以从__new__返回任何类型,而不是您应该在这里这样做)。 -
您为什么使用
__new__()方法而不是__init__()?请注意,在您的情况下,__new__()返回的任何内容都会分配给var1。 -
这看起来更像是
__init__的工作,而不是__new__。__new__通常用于(逻辑上或物理上)不可变对象。 -
如果我可以直接分配给“self”,而不仅仅是 self 的属性,我会使用 init。那么,有没有办法在 init 中真正做到这一点?如何从列表对象创建方数组并仅返回方数组?我不希望返回类似于“self.yourArray”之类的东西,但就像“self”一样,我认为该类定义了对象类型。
-
我将 'return' 更改为 ``` return list.__new__(cls, template) ''' 并且 "str" 现在可以工作并且类型反映为 " ArrayList”,非常感谢。它仍然在“var1 is ArrayList”上显示错误,但“is”应该是“isinstance”,这也有效!非常感谢!
标签: python python-3.x list class