返回自我python的目的

Amr*_*ndy 13 python return

我有问题 return self

class Fib: 
    def __init__(self, max):
        self.max = max
    def __iter__(self): 
        self.a = 0
        self.b = 1
        return self
    def __next__(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib
Run Code Online (Sandbox Code Playgroud)

我已经看到这个问题回归自我问题,但我无法理解它的好处是return self什么?

jua*_*aga 18

返回self从一个方法只是意味着你的方法返回到它被调用实例对象的引用.有时可以看到这与面向对象的API一起使用,这些API被设计为一个鼓励方法级联流畅接口.所以,例如,

>>> class Counter(object):
...     def __init__(self, start=1):
...         self.val = start
...     def increment(self):
...         self.val += 1
...         return self
...     def decrement(self):
...         self.val -= 1
...         return self
...
>>> c = Counter()
Run Code Online (Sandbox Code Playgroud)

现在我们可以使用方法级联:

>>> c.increment().increment().decrement()
<__main__.Counter object at 0x1020c1390>
Run Code Online (Sandbox Code Playgroud)

请注意,在最后一次调用decrement()返回<__main__.Counter object at 0x1020c1390>,这 self.现在:

>>> c.val
2
>>>
Run Code Online (Sandbox Code Playgroud)

请注意,如果您没有返回,则无法执行此操作self:

>>> class Counter(object):
...     def __init__(self, start=1):
...         self.val = start
...     def increment(self):
...         self.val += 1
...         # implicitely return `None`
...     def decrement(self):
...         self.val -= 1
...         # implicitely return `None`
...
>>> c = Counter()
>>> c.increment().increment()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'increment'
>>> c
<__main__.Counter object at 0x1020c15f8>
>>> c.val
2
>>>
Run Code Online (Sandbox Code Playgroud)

请注意,并非每个人都是"方法级联"设计的粉丝.Python内置函数不倾向于这样做,因此,list例如:

>>> x = list()
>>> x.append(1).append(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'append'
>>>
Run Code Online (Sandbox Code Playgroud)

在一个地方,你经常看到这是当你的类实现了iterator协议,其中iter在一个迭代收益self按照惯例,虽然这是建议的文档:

看过迭代器协议背后的机制,很容易将迭代器行为添加到类中.定义一个使用__iter__()方法返回对象的__next__()方法.如果类定义了__next__(),那么__iter__()可以返回self:

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]
Run Code Online (Sandbox Code Playgroud)

请注意,这实际上使您的迭代器仅对单个传递有用:

>>> x = [1, 2, 3, 4]
>>> it = iter(x)
>>> list(it)
[1, 2, 3, 4]
>>> list(it)
[]
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
Run Code Online (Sandbox Code Playgroud)