python - 为什么我的类的 __new__() 方法不返回该类的实例?

标签 python python-3.x list class

我正在尝试找出一种创建预先确定尺寸的列表的方法,以避免列表对象的限制,例如无法插入远远超过列表末尾的内容。所以这段代码按照我想要的方式构建了列表,但直到我开始实现 __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

最佳答案

您可以使用collections.UserList 。它是为子类化列表而设计的。这将允许您使用相同的代码在 __init__() 中分配给 self.data 并避免 __new__() 的问题:

from collections import UserList
import copy

class ArrayList(UserList):
    def __init__(self, *dim, initial = []):
        self.data = None
        for d in range(len(dim)-1, -1, -1):
            if self.data is None:
                self.data = [initial for _ in range(dim[d])]
            else:
                self.data = [copy.deepcopy(self.data) for _ in range(dim[d])]

    def __str__(self):
        return '\n'.join(str(s) for s in self)

var1 = ArrayList(4,3,2,initial=0)
print(var1)
print(type(var1))   # <class 'list'>
print(isinstance(var1, ArrayList))

打印:

[[0, 0], [0, 0], [0, 0]]
[[0, 0], [0, 0], [0, 0]]
[[0, 0], [0, 0], [0, 0]]
[[0, 0], [0, 0], [0, 0]]
<class '__main__.ArrayList'>
True

请注意,文档建议:

Subclasses of UserList are expected to offer a constructor which can be called with either no arguments or one argument...

...If a derived class does not wish to comply with this requirement, all of the special methods supported by this class will need to be overridden

您没有在这里执行此操作(尽管这对于您的目的可能并不重要)。

此外,如果您还没有考虑过,使用 Numpy 可能会更容易:

import numpy as np
np.zeros([4, 3, 2])

关于python - 为什么我的类的 __new__() 方法不返回该类的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63429001/

相关文章:

python - 什么是单一引用的高效容器?

java - 获取列表的大小会使我的程序崩溃

python - Scikit 学习错误消息 'Precision and F-score are ill-defined and being set to 0.0 in labels'

python - pymssql:与数据库的连接有时有效

python - 将 N 维数组广播到 (N+1) 维数组并对除 1 维之外的所有维求和

python-3.x - Azure 认知搜索 : Use Suggested questions to query Search Index

python - Python 中的相同对象问题

Java Wildfly POST 方法 multipart/form-data : "Unable to get boundary..."

python-3.x - 如何预填充并保存 Django 模型记录而不覆盖当前记录?

Python:列表匹配