是否有一种内置方式(例如,装饰器)在definiton实例化Python生成器?

是否有一种内置方式(例如,装饰器)在definiton实例化Python生成器?,python,generator,decorator,Python,Generator,Decorator,是否有内置/推荐的方法来替换装饰器: def发生器(f): 返回f() 在下面的例子中 来自随机导入randint @发电机 def mygenerator(): 尽管如此: 收益率randint(0,9) 对于mygenerator中的i: 打印i 。。。正如我不想写的: mygenerator()中的i的: 打印i 这是一个简化的例子。在实际用例中,没有必要/理由拥有两个mygenerator实例,因此我想立即创建实例。最好不要创建其他实例。内置的方法如下: def mygenerat

是否有内置/推荐的方法来替换装饰器:

def发生器(f): 返回f() 在下面的例子中

来自随机导入randint
@发电机
def mygenerator():
尽管如此:
收益率randint(0,9)
对于mygenerator中的i:
打印i
。。。正如我不想写的:

mygenerator()中的i的
:
打印i

这是一个简化的例子。在实际用例中,没有必要/理由拥有两个
mygenerator
实例,因此我想立即创建实例。最好不要创建其他实例。

内置的方法如下:

def mygenerator():
    while True:
        yield randint(0, 9)

mygenerator = mygenerator()

这至少具有清晰的优点,因此您不必查找
@generator
的功能。

可以使用
()
语法创建生成器-即

mygenerator = (randint(0, 9) for i in range(0, 100))
但我想,你的问题是发电机是无限的——你可以试试这个:

import itertools
from random import randint

mygenerator = (randint(0, 9) for i in itertools.count())

有关更多详细信息,请参见。某些语言有一个名为
do
的二进制前缀运算符,用于调用其参数:

generator = do <generator expression>
您必须预先定义函数或生成器:

def generator(): yield
generator = decorator(generator)
主要是语法限制迫使Python采用
@
语法来装饰用
def
语句定义的函数。以下代码与上一个示例等效(除了在指定名称时的细微差异):

正如格雷格所提到的,有一些生成器理解,在你可以使用它们的地方,它们工作得非常好,但是如果你的身体需要更多的逻辑,那么你所做的似乎是最符合Python的方式。只是Python语法总是让函数式编程变得相当笨拙


您在评论中询问了具有
do
运算符的语言。CoffeeScript和Haskell都有。老实说,我不太明白,但在CoffeeScript中,
do
对于在闭包中创建值很有用

看看这段代码(下面有一个解释)

在JS中是这样的:

let updateElementText = function() {
  let element = jQuery("#someElement");
  return function(newText) { element.text(newText) };
}(); // Immediately-Invoked Function Expression (IIFE)

代码将
updateElementText
分配给第3行返回的函数,该函数通过闭包引用
元素。无论调用多少次
updateElementText
来更新元素,jQuery只选择一次元素(在第2行)。还要注意,
元素
是隐藏的,因此它只能由更新它的函数引用。

是否有任何不需要/理由?有了这样一个简单的例子,您可能可以使用
itertools
而不是函数来实现它。是的。我试图在最后一段中澄清,这完全过于简单化了。。。假设我想在
mygenerator
的定义中做一些复杂的事情。并避免创建两个实例。@azrael:如果您希望这些“复杂的事情”在定义时发生,那么您所要求的不会产生这种效果。在第一个
下一个
之前,不会执行任何生成器函数体。另外,如果您想避免创建两个迭代器,我建议您不要创建两个迭代器,而不要用返回值替换函数。第一部分,这不是我所关心的。我对执行的身体很满意,例如,在for循环中。我只是不想再出现这个函数了。所以,原则上,我想我想要一个生成器表达式,它允许更复杂的事情(就像其他答案中的共识一样)…啊,对了!这确实是我应该做的。我没有想到简单地用它的结果覆盖函数(即使这是decorator所做的)…无限循环不一定是问题所在。正如我试图说的,这是一个简化的例子。假设,我想在
mygenerator
中完成一些不能作为生成器表达式完成的复杂操作。但你肯定是对的:这些不能被实例化两次。请注意,哪些语言有这样的
do
操作符?在阅读了答案之后,我认为如果我有许多单实例生成器,我所做的是很好的。然而,我不知道——这只是其中之一。所以,我想金德的答案是正确的。我在答案中添加了一些东西,但是的,金德是对的。如果你只做一次,最好把它写清楚,并重复使用这个名字。如果你在多个地方有相同的图案,你原来的装饰师会更好。现在我知道这和我的问题相比是什么了。谢谢你联系我。诚然,我也无法理解哈斯克尔的例子;-)我想,一个人不能简单地跳转到一门未知语言的最高级主题,并期望理解它。看来,是时候学习哈斯克尔了。
@decorator
def generator(): yield
updateElementText = do ->
  element = jQuery "#someElement"
  return (newText) -> element.text newText
let updateElementText = function() {
  let element = jQuery("#someElement");
  return function(newText) { element.text(newText) };
}(); // Immediately-Invoked Function Expression (IIFE)