返回self python的目的 [英] Purpose of return self python

查看:82
本文介绍了返回self python的目的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有return self

的问题

类 Fib:def __init__(self, max):self.max = 最大值def __iter__(self):自我.a = 0自我.b = 1回归自我def __next__(self):fib = self.a如果 fib >self.max:引发停止迭代self.a, self.b = self.b, self.a + self.b返回 fib

我已经看过这个问题返回自身问题 但我不明白return self 的好处是什么?

解决方案

从方法返回 self 仅仅意味着您的方法返回对调用它的实例对象的引用.这有时可以在面向对象的 API 中看到,这些 API 设计为 流畅的界面,鼓励 方法级联.因此,例如,

<预><代码>>>>类计数器(对象):... def __init__(self, start=1):... self.val = 开始...定义增量(自我):... self.val += 1... 回归自我... def 递减(自我):... self.val -= 1... 回归自我...>>>c = 计数器()

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

<预><代码>>>>c.increment().increment().decrement()<__main__.Counter 对象在 0x1020c1390>

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

<预><代码>>>>值2>>>

注意,如果你没有返回self,你就不能这样做:

<预><代码>>>>类计数器(对象):... def __init__(self, start=1):... self.val = 开始...定义增量(自我):... self.val += 1... # 隐式返回 `None`... def 递减(自我):... self.val -= 1... # 隐式返回 `None`...>>>c = 计数器()>>>c.increment().increment()回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中AttributeError: 'NoneType' 对象没有属性 'increment'>>>C<__main__.Counter 对象在 0x1020c15f8>>>>值2>>>

请注意,并非所有人都喜欢方法级联"设计.Python 内置函数不会这样做,因此,list 例如:

<预><代码>>>>x = 列表()>>>x.append(1).append(2)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中AttributeError: 'NoneType' 对象没有属性 'append'>>>

经常看到的一个地方是你的类实现了iterator协议,其中迭代器上的iter返回self 按照惯例,尽管这是由 文档 建议的:

<块引用>

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

class 反向:"""用于向后循环序列的迭代器."""def __init__(self, data):self.data = 数据self.index = len(数据)def __iter__(self):回归自我def __next__(self):如果 self.index == 0:引发停止迭代self.index = self.index - 1返回 self.data[self.index]

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

<预><代码>>>>x = [1, 2, 3, 4]>>>它 = iter(x)>>>列表(它)[1, 2, 3, 4]>>>列表(它)[]>>>下一个(它)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中停止迭代>>>

I have a problem with 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

I have already seen this question return self problem but I can't understand what the benefit is of return self?

解决方案

Returning self from a method simply means that your method returns a reference to the instance object on which it was called. This can sometimes be seen in use with object oriented APIs that are designed as a fluent interface that encourages method cascading. So, for example,

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

Now we can use method cascading:

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

Notice, the last call to decrement() returned <__main__.Counter object at 0x1020c1390>, which is self. Now:

>>> c.val
2
>>>

Notice, you cannot do this if you did not return 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
>>>

Notice, not everyone is a fan of "method cascading" design. Python built-ins do not tend do this, so, list for example:

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

The one place you do often see this is when your class implements the iterator protocol, where iter on an iterator returns self by convention, although this is suggested by the docs:

Having seen the mechanics behind the iterator protocol, it is easy to add iterator behavior to your classes. Define an __iter__() method which returns an object with a __next__() method. If the class defines __next__(), then __iter__() can just return 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]

Notice, this in effect makes your iterator only useful for a single pass (as it should be to properly follow the iterator protocol):

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

这篇关于返回self python的目的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆