如何从python的zip继承而使用类attrs?

时间:2019-03-21 19:26:10

标签: python

我遇到了一个有趣的问题...我试图对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)

这是为什么?

3 个答案:

答案 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仅由SomeClasszipobject组成),该参数不包含任何参数。调用之后,您可以设置自己的属性。

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)