Python 中产出关键字的用法是什么? 它能做什么?
例如,我试图理解这个代码1:
def _get_child_candidates(self, distance, min_dist, max_dist):
if self._leftchild and distance - max_dist < self._median:
yield self._leftchild
if self._rightchild and distance + max_dist >= self._median:
yield self._rightchild
这就是打电话的人:
result, candidates = [], [self]
while candidates:
node = candidates.pop()
distance = node._get_dist(obj)
if distance <= max_dist and distance >= min_dist:
result.extend(node._values)
candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result
当方法 _get_child_camedates 被调用时会怎样? 列表是否返回? 单一个元素吗? 是否再次调用? 以后的电话何时停止?
1. 本代码由Jochen Schulz(jrschulz)编写,他为公制空间制作了一个伟大的Python图书馆,与完整的源:模块mspace链接。
(我下面的回答只是从使用Python发电机的角度,而不是从发电机机制的基本实施角度,后者涉及一些堆叠和堆积操纵的伎俩。 )
当在 python 函数中使用 quot 而不是返回时, 该函数将被转换为特殊的名称 。 此函数将返回生成器类型的对象 。 产量关键字是提醒 python 编译器专门处理此函数的旗帜 。 正常函数一旦从中返回某些值就会终止 。 但是, 在编译器的帮助下, 生成器的函数可以被视为可恢复 。 也就是说, 执行环境将会恢复, 执行会从上次运行时继续 。 直到您明确调回, 这会引起一个停止引力例外( 也是循环协议的一部分) , 或者到达函数的终点 。 我发现许多关于生成器的引用, 但从功能编程角度来说, 这是一种最可消化的引用 。
(现在我想谈谈产生者背后的理由, 以及基于我自己的理解的循环器。 我希望这能帮助你掌握循环器和生成者的基本动机。 这一概念以其他语言出现, 如 C# 。 )
据我所知,当我们想要处理一大批数据时,我们通常先在某处储存数据,然后逐个处理。但这种天真的方法有问题。如果数据量很大,那么事先将数据全部储存起来费用很高。因此,与其直接储存数据本身,不如间接储存某种元数据,即数据计算逻辑。
有两种方法可以包扎这类元数据。
OO 方法, 我们把元数据包成一个类。 这是执行循环协议( 即 __ next_ () 和 __ ter_ () 方法) 的所谓迭代器。 这也是常见的迭代器设计模式 。 功能方法, 我们将元数据包成函数 。 这是所谓的生成功能 。 但是在引擎盖下, 返回的生成对象仍然是 IS - A 迭代器, 因为它也执行循环程序 。
无论哪种方式, 都会创建一个迭代器, 即某个可以提供您想要的数据的对象。 OO 处理方式可能有点复杂。 总之, 由您决定使用哪一种 。
以下是一个简单的例子:
def isPrimeNumber(n):
print "isPrimeNumber({}) call".format(n)
if n==1:
return False
for x in range(2,n):
if n % x == 0:
return False
return True
def primes (n=1):
while(True):
print "loop step ---------------- {}".format(n)
if isPrimeNumber(n): yield n
n += 1
for n in primes():
if n> 10:break
print "wiriting result {}".format(n)
产出:
loop step ---------------- 1
isPrimeNumber(1) call
loop step ---------------- 2
isPrimeNumber(2) call
loop step ---------------- 3
isPrimeNumber(3) call
wiriting result 3
loop step ---------------- 4
isPrimeNumber(4) call
loop step ---------------- 5
isPrimeNumber(5) call
wiriting result 5
loop step ---------------- 6
isPrimeNumber(6) call
loop step ---------------- 7
isPrimeNumber(7) call
wiriting result 7
loop step ---------------- 8
isPrimeNumber(8) call
loop step ---------------- 9
isPrimeNumber(9) call
loop step ---------------- 10
isPrimeNumber(10) call
loop step ---------------- 11
isPrimeNumber(11) call
我不是Python开发者,但对我来说,它似乎保持了程序流程的位置,而下一个循环则从“当量”的位置开始。 它似乎正在等待着这个位置,就在那个位置之前,它正在向外回报一个价值,而下一次将继续工作。
这似乎是一个有趣和好的能力:
和每个答案一样, 收益被用于创建序列生成器。 它用于动态生成某些序列。 例如, 在按行阅读网络文件行时, 您可以使用以下的收益函数 :
def getNextLines():
while con.isOpen():
yield con.read()
您可在您的代码中使用以下代码:
for line in getNextLines():
doSomeThing(line)
执行控制控制
执行控制将会从 GetNextLines () 转到执行时的循环。 因此, 每次引用 NextLines () 时, 执行都会从上次暂停处开始 。
因此,简言之,一个函数具有以下代码
def simpleYield():
yield "first time"
yield "second time"
yield "third time"
yield "Now some useful value {}".format(12)
for i in simpleYield():
print i
将打印
"first time"
"second time"
"third time"
"Now some useful value 12"
- 功能 - 返回。
发电机 -- -- 产量(含有一个或多个产量和零或更多回报率)。
names = ['Sam', 'Sarah', 'Thomas', 'James']
# Using function
def greet(name) :
return f'Hi, my name is {name}.'
for each_name in names:
print(greet(each_name))
# Output:
>>>Hi, my name is Sam.
>>>Hi, my name is Sarah.
>>>Hi, my name is Thomas.
>>>Hi, my name is James.
# using generator
def greetings(names) :
for each_name in names:
yield f'Hi, my name is {each_name}.'
for greet_name in greetings(names):
print (greet_name)
# Output:
>>>Hi, my name is Sam.
>>>Hi, my name is Sarah.
>>>Hi, my name is Thomas.
>>>Hi, my name is James.
发电机看起来像一个函数,但行为举止却像一个迭代器。
发件人继续从它所在的位置执行 。 恢复后, 函数在最后产值运行后立即继续执行 。 这允许它的代码在一段时间内生成一系列的值, 代之以它们一次性计算全部值, 然后把它们像列表一样送回去 。
def function():
yield 1 # return this first
yield 2 # start continue from here (yield don't execute above code once executed)
yield 3 # give this at last (yield don't execute above code once executed)
for processed_data in function():
print(processed_data)
#Output:
>>>1
>>>2
>>>3
注:放弃不应在尝试中.最终建造。