[英]How to inherit from python's zip but use class attrs?
I ran into an interesting issue... I was trying to SubClass python's zip
type... I wanted to create a class that acted as a zip
yet has class attrs. 我遇到了一个有趣的问题...我试图对python的
zip
类型进行SubClass ...我想创建一个充当zip
的类,但具有class attrs。
At First I tried 起初我尝试过
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)
But it seems like zip
's __init__
takes nothing but self
? 但是似乎
zip
的__init__
除了self
什么都不做?
So I tried 所以我尝试了
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)
Which works but requires I do x=SomeClass().new()
哪个有效,但需要我执行
x=SomeClass().new()
Finally I got to this... 终于我明白了...
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)
This runs __init__
twice... I am just curious if there is a way to circumvent this or will class attrs never exist at the time __new__
runs? 这两次运行
__init__
我只是好奇是否有办法绕过这个问题,或者在__new__
运行时是否永远不会存在类attrs?
UPDATE: This ALMOST works 更新:此ALMOST有效
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)
How ever x
and y
are not instance variables :(. Example x
和y
不是实例变量:(。
class SomeClass(zip):
def __new__(self, x, y):
self.x = x
self.y = y
return super().__new__(self, self.x, self.y)
>>> k=SomeClass([1,2],[3,4])
>>> k.x
[1, 2]
>>> j=SomeClass([2,2],[4,4])
>>> j.x
[2, 2]
>>> k.x
[2, 2]
Why is this? 为什么是这样?
Your problem is that you're trying to use the object attributes self.x
and self.y
in __new__
, where self
doesn't actually exist yet. 你的问题是,你要使用的对象属性
self.x
和self.y
在__new__
,其中self
实际上并不存在呢。 (The thing you've so inappropriately labeled self
is actually the class.) You're going about this backwards. (你这么不恰当地标示事情
self
实际上是类。)你倒退这个问题。 First, __new__
must create an object ( self
), and only then can you call __init__
. 首先,
__new__
必须创建一个对象( self
), 然后才能调用__init__
。 (You shouldn't, though, because python will do it for you automatically.) (不过,您不应该这样做,因为python会自动为您完成此操作。)
Now, as you've already found out, you have to have access to x
and y
before __init__
is executed (because you have to pass them to zip.__new__
). 现在,您已经发现,必须在执行
__init__
之前访问x
和y
(因为必须将它们传递给zip.__new__
)。 Because of this, it's easiest to initialize x
and y
directly in __new__
. 因此,最简单的方法是直接在
__new__
初始化x
和y
。 (The __init__
then no longer serves a purpose, so it can be removed.) (然后,
__init__
不再__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')
Demo: 演示:
>>> 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)]
zip
doesn't define __init__
. zip
没有定义__init__
。 super().__init__
actually calls object.__init__
(since in this example, the MRO consists of just SomeClass
, zip
, and object
), which expects no arguments. super().__init__
实际上会调用object.__init__
(因为在此示例中,MRO仅由SomeClass
, zip
和object
),它不需要任何参数。 After calling that, you can set your own attributes. 调用之后,您可以设置自己的属性。
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])
If you don't care about cooperative inheritance, you can simplify it to 如果您不关心协作继承,则可以将其简化为
class SomeClass(zip):
def __init__(self, *args):
self.x = np.array([1,2,3,4])
self.y = np.array([1,4,9,16])
While I'm not sure to understand the purpose of this, you can do it by using delegation instead of inheritance: 虽然我不确定要了解的目的,但是可以通过使用委托而不是继承来做到这一点:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.