返回self python的目的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43380042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Purpose of return self python
提问by AmrElgendy
I have a problem with return self
我有问题 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 problembut I can't understand what the benefit is of return self
?
我已经看到这个问题返回自我问题,但我不明白有什么好处return self
?
回答by juanpa.arrivillaga
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 interfacethat encourages method cascading. So, for example,
返回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()
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 isself
.
Now:
请注意,最后调用decrement()
返回<__main__.Counter object at 0x1020c1390>
,这是self
。现在:
>>> c.val
2
>>>
Notice, you cannot do this if you did not return self
:
请注意,如果您没有返回,则无法执行此操作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:
请注意,并不是每个人都喜欢“方法级联”设计。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'
>>>
The one place you dooften 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:
你的一个地方就经常看到这是当你的类实现了iterator
协议,其中iter
在一个迭代收益self
按照惯例,虽然这是建议的文档:
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 returnself
: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]
了解了迭代器协议背后的机制后,很容易将迭代器行为添加到您的类中。定义一个
__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]
Notice, this in effect makes your iterator only useful for a single pass (as it shouldbe 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
>>>
回答by Adam Smith
This is needlessly complex code. Pay little attention to it. There's no reason on earth to implement it this way.
这是不必要的复杂代码。很少注意它。地球上没有理由以这种方式实现它。
That being said, what it does is this:
话虽如此,它的作用是这样的:
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
This is all much easier to express as:
这更容易表达为:
def fib(max_):
a, b = 0, 1
while b <= max_:
out = a
a, b = b, a+b
yield out
Examples:
例子:
>>> 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