在definiton中实例化Python生成器有没有一种内置方法(例如,decorator)?

2024-10-02 22:27:49 发布

您现在位置:Python中文网/ 问答频道 /正文

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

def generator(f):
    return f()

在下面的例子中?你知道吗

from random import randint

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

for i in mygenerator:
    print i

。。。因为我不想写:

for i in mygenerator():
    print i

这是一个简化的例子。在实际用例中,没有必要/理由拥有两个mygenerator实例,因此我想马上创建这个实例。最好是以不能创建其他实例的方式。你知道吗


Tags: 实例方法infromforreturndef装饰
3条回答

其内在方法如下:

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

有关更多详细信息,请参见this answer

你所做的是尽可能地地道。有些语言有一个名为do的二进制前缀运算符,它调用它的参数:

generator = do <generator expression>

Python语法不允许将多行函数编写为表达式。您必须使用def语句。这就是为什么在Python中不能使用常规调用将多行函数或生成器传递给装饰器的原因:

generator = decorator(def generator(): yield) # syntax error

您必须预先定义函数或生成器:

def generator(): yield
generator = decorator(generator)

主要是语法限制迫使Python采用@语法来修饰用def语句定义的函数。下面的代码相当于上一个示例(除了在中当指定名称时的细微差别外):

@decorator
def generator(): yield

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


您在评论中询问了有关使用do运算符的语言。CoffeeScript和Haskell都有。老实说,我不太了解anything the Haskell docs say,但是在CoffeeScript中,do对于在闭包中创建值很有用。你知道吗

看看这个代码(下面有一个解释)。你知道吗

updateElementText = do ->
  element = jQuery "#someElement"
  return (newText) -> element.text newText

在JS中是这样的:

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

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

相关问题 更多 >