没有调用__getitem__和__setitem__

Tam*_*ton 0 python

我有以下类定义:

class Codes():
    def __new__(self, inp):
        self.data = np.zeros((50,50))
        self.capacity = 50
        self.size = 6
        self.data[:self.size,:self.size] = inp
        self.x = 0
        self.y = 0

        return self

    def __setitem__(self,coords,value):
        x = coords[0]
        y = coords[1]
        if max(x,y) >= self.capacity:
            self.capacity *= 2
            newdata = np.zeroes((self.capacity,))
            newdata[:self.size,:self.size] = self.data
            self.data = newdata

        self.data.__setitem__(coords,value)

        if max(x,y) >= self.size:
            print("expanding")
            self.size = max(x,y)
        print ("Debug")
    def __getitem__(self,coords):
        x = coords[0]
        y = coords[1]
        return self.data[x,y]
Run Code Online (Sandbox Code Playgroud)

似乎没有调用get和set方法.我正在初始化:

inp = np.array([[20151125,18749137,1728984,30943339,10071777,33511524],
               [31916031,21629792,16929656,7726640,15514188,4041754],
               [16080970,8057251,1601130,7981243,11661866,16474243],
               [24592653,32451966,21345942,9380097,10600672,31527494],
               [77061,17552253,28094349,6899651,9250759,31663883],
               [33071741,6796745,25397450,24659492,1534922,27995004]])
a = Codes(inp)
Run Code Online (Sandbox Code Playgroud)

如果我尝试然后执行print(a[1,1]),我得到错误:

Traceback (most recent call last):
  File "C:/Users/cotont/Dropbox/Advent of Code/Advent of Code 25-1.py", line 55, in <module>
    print(a[1,1])
TypeError: 'type' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)

如果我尝试执行a[49,49] = 1,我得到:

Traceback (most recent call last):
  File "C:/Users/cotont/Dropbox/Advent of Code/Advent of Code 25-1.py", line 55, in <module>
    a[49,49] = 1
TypeError: 'type' object does not support item assignment
Run Code Online (Sandbox Code Playgroud)

为什么我的自定义方法没有被调用,我该如何解决?

Mar*_*ers 6

您误解了__new__应该使用的地方或意外使用的地方__init__.您将通过返回返回Codes对象本身self:

def __new__(self, inp):
    # ...
    return self
Run Code Online (Sandbox Code Playgroud)

__new__被称为类的静态方法,并期望在该方法中生成一个新实例.

因为您返回了类型对象(类),__getitem__并且__setitem__查找了type(默认元类)(请参阅特殊方法查找),但失败了.

你可能想在__init__那里使用; __init__在已创建的实例上调用:

class Codes():
    def __init__(self, inp):
        self.data = np.zeros((50,50))
        self.capacity = 50
        self.size = 6
        self.data[:self.size,:self.size] = inp
        self.x = 0
        self.y = 0
Run Code Online (Sandbox Code Playgroud)

__init__不需要返回任何东西(无论如何它都会被忽略),所以你可以return self完全放弃这一行.

如果您觉得必须使用__new__(可能是因为您是子类化不可变类型),那么至少要创建一个实例super().__new__():

class Codes():
    def __new__(cls, inp):
        instance = super(Codes, cls).__new__(cls)
        instance.data = np.zeros((50,50))
        instance.capacity = 50
        instance.size = 6
        instance.data[:self.instance,:instance.size] = inp
        instance.x = 0
        instance.y = 0
        return instance
Run Code Online (Sandbox Code Playgroud)

但使用__init__相反只是更简单.