为什么python生成器和函数共享“ def”关键字?


10

考虑以下:

def some_function():
    return 1

def some_generator():
    yield 1

在上面的代码中,some_function是一个函数,some_generator而是一个生成器。他们看起来很相似。

我在阅读代码时遇到的问题是,我需要在“函数”的每一行中进行扫描以寻找yield关键字,然后才能确定它实际上是函数还是生成器!

在我看来,为生成器使用其他关键字会更有意义,例如:

gen some_generator():
    yield 1

def对生成器和函数使用关键字有什么好处?为什么未将新关键字引入单独的函数和生成器?


我不知道真正的答案,但是我经常开始写返回列表的函数,然后在看起来合适的时候转换为生成器。语法匹配使之更加自然。
Gort机器人2015年

2
@StevenBurnap Derek的建议是使用类似gen而不是类似的方法,def这不会使转换变得更加繁重。
jamesdlin

2
通常,语言设计人员通常会尝试避免添加不必要的关键字。他们添加的每个关键字都是一个标识符,程序不得将其用于其他目的。
jamesdlin

@jamesdlin:但问题是争论是否有必要使用新的关键字。
Giorgio

1
@jamesdlin:当然,您可以通过查看函数和生成器的主体来区分它们,但是问题是使用不同的关键字会使代码更具可读性。
Giorgio

Answers:


14

“将def关键字用于生成器和函数有什么好处?”

尽管它们在机械上有所不同,但在实践中,当我使用它们时,它们在概念上通常对我实际上是相同的(我不太喜欢称呼range()vs xrange())。

就快速了解功能的意义而言,我同意使用会丢失一些东西def,但一开始不要在功能内混淆太多。

即使是隐式的,return None也可以在长时间的条件之后混淆函数的预期行为(例如,将return None其作为最终行为或逻辑中的监督)。但是这些只是我的想法。

我觉得我的论点并不是特别有说服力,所以我只想参考PEP 255

问题:引入另一个新关键字(例如,“ gen”或“ generator”)代替“ def”,或以其他方式更改语法,以区分生成器功能与非生成器功能。

缺点:在实践中(您如何看待它们),生成器 函数,但具有可恢复性的缺点。如何设置它们的技巧是一个相对较小的技术问题,并且引入新关键字将无助地过分强调发电机启动的机制(发电机生命中至关重要但很小的一部分)。

Pro:实际上(生成器的功能),生成器函数实际上是工厂函数,它们像魔术一样生成生成器迭代器。在这方面,它们与非生成器函数有根本的不同,它们的行为更像是构造函数,而不是函数,因此重用“ def”充其量是令人困惑的。掩埋在体内的“屈服”声明不足以警告语义如此不同。

BDFL:“ def”保持不变。任何一方的论点都不是完全令人信服的,因此我已经咨询了语言设计师的直觉。它告诉我,PEP中建议的语法是正确的-不太热也不是太冷。但是,就像希腊神话中的Delphi上的Oracle一样,它没有告诉我原因,因此我没有反驳PEP语法的论点。我能想到的最好的方法(除了同意反驳……已经做出的建议)是“ FUD”。如果从一开始它就已经成为语言的一部分,那么我非常怀疑这是否会使Andrew Kuchling的“ Python Warts”页面成真。


1
值得一提的是,新的await(和 async withasync for)语法结构中加入PEP 492,这工作很相似yield from,要求他们在使用声明中使用的功能async def,而不是公正def
Feuermurmel

2
  1. 添加新关键字可能会破坏现有程序。 语言设计人员通常会尝试避免添加新的关键字,尤其是对于已获得某种流行度的语言功能。他们添加的每个关键字都是不允许程序用于其他目的的标识符,因此添加关键字可能会破坏现有程序。语言设计师必须权衡使用新关键字的收益和成本。

  2. 我怀疑为生成器定义一个单独的关键字是否会带来很多好处。要了解符号是对应于函数名还是生成器名,对调用者来说很重要,调用者不必(有时也不必)看看使用了什么关键字来实现它。这是更好的命名约定和文档的责任。


1

生成器是懒惰求值的函数。考虑到它们在根本上是同一件事,因此使用相同的关键字是有意义的。一种选择可能是使用注释来标识给定实例的哪个:

def some_function(): #This is a function.
    return 1

def some_generator(): #This is a generator.
    yield 1

0

我猜这是因为它更像Python,但是我知道什么呢?;)

我真的不认为这很重要。对我来说,记住起来比较容易,因为不需要记住它们两者。

编辑:PEP可能会说,您可以在那里进行调查。


谢谢!实际上,PEP确实会说!有关生成器的新关键字的优缺点和最终决定,请参阅PEP-255
郭峰(Derek Kwok)2015年

具有Pythonic含义:“在Python中完成的方式”?
Giorgio
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.