我有类Count,它有3个参数,包括self,mystart和myend。它应该使用魔术方法__iter__
,__next__
和__reversed__
计算从mystart到myend(也是反转)。我已经实现了所有三种魔术方法。但我仍然不确定它是否是实施下一步和反向方法的正确方法。是否有可能我可以在我的__next__
和__reversed__
方法中调用内置函数并进行反转,还是有任何pythonic方式?
class Count:
def __init__(self,mystart,myend):
self.mystart=mystart
self.myend=myend
self.current=mystart
self.reverse=[]
def __iter__(self):
"Returns itself as an Iterator Object"
return self
def __next__(self):
if self.current > self.myend:
raise StopIteration
else:
self.current+=1
return self.current-1
def __reversed__(self):
for i in range(self.myend,self.mystart,-1):
self.reverse.append(i)
return self.reverse
obj1=Count(0,10)
print("FOR LOOP")
for i in obj1:
print (i,end=",")
print ("\nNEXT")
obj2=Count(1,4)
print(next(obj2))
print(next(obj2))
print ("Reversed")
print(reversed(obj1))
答案 0 :(得分:1)
现在我使用yield语句完成了它。 @jedwards感谢你的tipp。
class Count:
def __init__(self, mystart,myend):
self.mystart = mystart
self.myend = myend
self.current=None
def __iter__(self):
self.current = self.mystart
while self.current < self.myend:
yield self.current
self.current += 1
def __next__(self):
if self.current is None:
self.current=self.mystart
if self.current > self.myend:
raise StopIteration
else:
self.current+=1
return self.current-1
def __reversed__(self):
self.current = self.myend
while self.current >= self.mystart:
yield self.current
self.current -= 1
obj1=Count(0,10)
for i in obj1:
print (i)
obj2=reversed(obj1)
for i in obj2:
print (i)
obj3=Count(0,10)
print (next(obj3))
print (next(obj3))
print (next(obj3))
答案 1 :(得分:1)
你正在混淆Iterators和Iterables:
迭代器:
__next__
以获得下一个州__iter__
返回。Iterables:
__iter__
以返回可遍历元素的迭代器__reversed__
以返回倒退的迭代器。 The __reversed__
magic method is:
通过reverse()内置调用(如果存在)来实现反向 迭代。它应该返回迭代的一个新的迭代器对象 容器中的所有对象的顺序相反。
所以你可能不希望实现迭代中可以__reversed__
迭代的迭代器,例如实现in your answer意味着这段代码:
x = Count(1,10)
for i in x:
for j in x:
print(i,j)
会导致无限循环,输出只是重复这种模式:
1 4
1 3
1 2
1 1
原因是因为两个for
循环在相反的方向上正在改变self.current
,外部循环将它递增1然后内部循环将其设置为self.myend
并降低它回到0,然后重复该过程。
正确实现所有三种魔术方法的唯一方法是使用两个类,一个用于迭代器,一个用于迭代:
class _Count_iter:
def __init__(self, start, stop, step=1):
self.current = start
self.step = step
self.myend = stop
def __iter__(self):return self
def __next__(self):
#if current is one step over the end
if self.current == self.myend+self.step:
raise StopIteration
else:
self.current+=self.step
return self.current-self.step
class Count:
def __init__(self, mystart,myend):
self.mystart = mystart
self.myend = myend
def __iter__(self):
return _Count_iter(self.mystart,self.myend,1)
def __reversed__(self):
return _Count_iter(self.myend, self.mystart, -1)