繁体   English   中英

返回self python的目的

[英]Purpose of return self python

我有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

我已经看到这个问题return self 问题,但我不明白return self什么好处?

从方法返回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()

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

>>> c.increment().increment().decrement()
<__main__.Counter object at 0x1020c1390>

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

>>> c.val
2
>>>

请注意,如果您没有返回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
>>>

请注意,并不是每个人都喜欢“方法级联”设计。 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'
>>>

经常会看到这样的一个地方是当你的类实现了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]

请注意,这实际上使您的迭代器仅对单次传递有用(因为它应该正确遵循迭代器协议):

>>> 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
>>>

这是不必要的复杂代码。 很少注意它。 地球上没有理由以这种方式实现它。

话虽如此,它的作用是这样的:

class Fib: 

    """Implements the Fibonacci sequence."""

    def __init__(self, max_):
        self.max = max_

    def __iter__(self):
        """Initializes and returns itself as an iterable."""

        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        """What gets run on each execution of that iterable."""

        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b  # increment
        return fib

这更容易表达为:

def fib(max_):
    a, b = 0, 1
    while b <= max_:
        out = a
        a, b = b, a+b
        yield out

例子:

>>> fib_obj = Fib(20)
>>> for n in fib_obj:
...     print(n)

>>> for n in Fib(20):
...     print(n)

>>> for n in fib(20):
...     print(n)
# all give....
0
1
1
2
3
5
8
13

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM