我遇到了一个有趣的问题...我试图对python的zip
类型进行子类化...我想创建一个充当zip
但又具有类attrs的类。
起初我尝试
class SomeClass(zip):
def __init__(self):
print('I ran')
self.x = np.array([1,2,3,4])
self.y = np.array([1,4,9,16])
super().__init__(self.x,self.y)
但是似乎zip
的{{1}}除了__init__
之外什么也没做?
所以我尝试了
self
哪个可以工作,但需要我class SomeClass(zip):
def __init__(self):
self.x = np.array([1, 2, 3, 4])
self.y = np.array([1, 4, 9, 16])
def new(self):
return zip.__new__(SomeClass, self.x, self.y)
最后我明白了...
x=SomeClass().new()
class SomeClass(zip):
def __init__(self):
print('I ran')
self.x = np.array([1,2,3,4])
self.y = np.array([1,4,9,16])
def __new__(self):
self.__init__(self)
return zip.__new__(self, self.x, self.y)
这两次运行for i in SomeClass():
... print(i)
...
I ran
I ran
(1, 1)
(2, 4)
(3, 9)
(4, 16)
...我只是想知道是否有一种方法可以避免这种情况,或者是否在__init__
运行时不存在类属性?
更新:此ALMOST有效
__new__
class SomeClass(zip):
def __new__(self):
self.x = np.array([1,2,3,4])
self.y = np.array([1,4,9,16])
return super().__new__(self, self.x, self.y)
和x
不是实例变量:(。示例
y
class SomeClass(zip):
def __new__(self, x, y):
self.x = x
self.y = y
return super().__new__(self, self.x, self.y)
这是为什么?
答案 0 :(得分:3)
您的问题是您试图使用self.x
中的对象属性self.y
和__new__
,其中self
实际上还不存在。 (您如此不恰当地将其标记为self
的东西实际上是该类。)您正在反向进行此操作。首先,__new__
必须创建一个对象(self
),只有 then 才能调用__init__
。 (不过,您不应该这样做,因为python会自动为您完成此操作。)
现在,正如您已经发现的那样,在执行 x
之前,您必须有权访问y
和__init__
(因为您必须将它们传递给zip.__new__
)。因此,最简单的方法是直接在x
中初始化y
和__new__
。 (__init__
不再具有用途,因此可以将其删除。)
class SomeClass(zip):
def __new__(cls):
x = [1, 2, 3, 4]
y = [1, 4, 9, 16]
obj = super().__new__(cls, x, y)
obj.x = x
obj.y = y
return obj
def __init__(self):
print('I ran')
演示:
>>> k = SomeClass()
I ran
>>> k.x
[1, 2, 3, 4]
>>> k.y
[1, 4, 9, 16]
>>> list(k)
[(1, 1), (2, 4), (3, 9), (4, 16)]
答案 1 :(得分:1)
zip
未定义__init__
。 super().__init__
实际上调用object.__init__
(因为在此示例中,MRO仅由SomeClass
,zip
和object
组成),该参数不包含任何参数。调用之后,您可以设置自己的属性。
class SomeClass(zip):
def __init__(self, *args, **kwargs):
super().__init__(**kwargs)
self.x = np.array([1,2,3,4])
self.y = np.array([1,4,9,16])
如果您不关心协作继承,可以将其简化为
class SomeClass(zip):
def __init__(self, *args):
self.x = np.array([1,2,3,4])
self.y = np.array([1,4,9,16])
答案 2 :(得分:0)
虽然我不确定要了解它的目的,但是可以通过使用委派而不是继承来做到这一点:
class SomeClass:
def __init__(self):
self.x = [1,2,3,4]
self.y = [1,4,9,16]
self.zipp = zip(self.x, self.y)
def __iter__(self):
return self.zipp
for x, y in SomeClass():
print(x, y)