首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >__reversed__魔术方法

__reversed__魔术方法
EN

Stack Overflow用户
提问于 2016-08-02 23:55:33
回答 2查看 1.1K关注 0票数 0

我有3个参数的类计数,包括self,mystart和myend。它应该使用魔法方法__iter____next____reversed__从mystart到myend (也是反向的)计数。我已经实现了所有三个魔术方法。但我仍然不确定这是不是实现next和reversed方法的正确方式。是否可以调用内置函数,然后在__next____reversed__方法中反转调用,或者有没有pythonic方式?

代码语言:javascript
复制
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))
EN

回答 2

Stack Overflow用户

发布于 2016-08-04 01:52:34

现在我已经使用Yeld语句完成了这项工作。@jedwards感谢你的tipp。

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2016-08-04 02:24:12

你混淆了迭代器和迭代器:

迭代器:

  1. 保持与其当前iteration progress
  2. Implement __next__相关联的状态,以使下一个iteration __iter__返回自己。

迭代:

  1. 包含(或用某种规则定义)一个元素集合,该集合可以是traversed
  2. Implement

返回一个可以遍历元素的迭代器

  1. 可以实现__reversed__以返回一个向后返回的迭代器。

The __reversed__ magic method is:

(如果存在)由内置的reversed()调用以实现反向迭代。它应该返回一个新的迭代器对象,该对象以相反的顺序迭代容器中的所有对象。

因此,您可能不希望实现一个可以在迭代中期执行的迭代器,例如,实现in your answer意味着以下代码:

代码语言:javascript
复制
x = Count(1,10)
for i in x:
    for j in x:
        print(i,j)

会导致无限循环,输出就是这个重复的模式:

代码语言:javascript
复制
1 4
1 3
1 2
1 1

这样做的原因是因为两个for循环在相反的方向上改变self.current,外部循环将其递增1,然后内部循环将其设置为self.myend并将其降低为0,然后重复该过程。

正确实现所有三个魔术方法的唯一方法是使用两个类,一个用于迭代器,另一个用于迭代器:

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38725269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档