Python `在`中为生成器定义

Python `在`中为生成器定义,python,python-3.8,Python,Python 3.8,为什么在中为发电机定义了 >>def foo(): ... 产量42 ... >>> >>>f=foo() >>>10英寸f 假的 可能的用例是什么 我知道范围(…)对象定义了一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu >>> r = range(10) >>> 4 in r True >>> r.__contains

为什么在中为发电机定义了

>>def foo():
...     产量42
... 
>>> 
>>>f=foo()
>>>10英寸f
假的

可能的用例是什么

我知道
范围(…)
对象定义了一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

>>> r = range(10)
>>> 4 in r
True
>>> r.__contains__
<method-wrapper '__contains__' of range object at 0x7f82bd51cc00>
>r=范围(10)
>>>4英寸r
真的
>>>r.。uu包含__

但是上面的
f
没有
\uuuuu contains\uuuu
方法。

生成器是可移植的,因此有一个
\uuuuu iter\uuuu
方法,可用于检查成员资格

有关其行为的说明,请参见

对于未定义但定义的用户定义类,如果在y上迭代时生成表达式为z或x==z的某个值
z
,则y中的
x
True
。如果在迭代过程中引发异常,就好像引发了该异常一样

我的

这会弹出整个生成器,而您的示例
42
根本不包括
10

>>def foo():
...     收益率5
...     收益率10
...
>>>f=foo()
>>>10英寸f
真的
>>>10英寸f
假的
“可能的用例是什么?”检查生成器是否会产生一些价值

Dunder方法充当它们所关联的特定语法的挂钩<代码>\uuuu包含\uuuu
不是某种一对一映射到y中的x
。语言最终定义了这些操作符的语义

从中,我们可以看到,根据所涉及对象的各种属性,有几种方法可以计算y中的x。我已经将生成器对象的相关参数调高,这些对象不定义
\uuuuu contains\uuuuu
,而是可编辑的,即它们定义了
\uuuuu iter\uuuuu
方法:

处于和未处于成员资格测试中的运算符<代码>s中的x计算结果为
True
如果x是s的成员,则为False<代码>x不在s中返回 s中x的否定。所有内置序列和集合类型都支持 这和字典一样,都在测试字典 有一个给定的键。对于容器类型,如列表、元组、集合, frozenset、dict或collections.deque,y中的表达式x为 相当于
any(x是e或x==e表示y中的e)

对于字符串和字节类型,
y中的x
True
当且仅当
x
y的子串
。等效测试是
y.find(x)!=-1
。空字符串 始终被视为任何其他字符串的子字符串,因此“abc”中的“
”将返回True

对于定义
方法的用户定义类,x在
如果
y,则y返回
True
。\uuu包含\uuuuuux)
返回真值,而
False
否则

用于不定义但包含()的用户定义类 定义
\uu iter\uu()
y中的x
True
如果某个值
z
,则 表达式
x为z或x==z
为true,在对
y
。如果在迭代过程中引发异常,则与 引发了该异常。

最后,尝试旧式的迭代协议:如果类定义
\uuu getitem\uuu()
y中的x
True
当且仅当存在一个非负整数索引
i
,使得
x为y[i]或x==y[i]
,且没有更低的整数 索引引发索引器异常。(如果存在任何其他例外情况 引发,就好像在引发异常一样)

运算符
不在
被定义为具有逆真值in

总之,将为以下对象定义y中的x

  • 是字符串或字节,定义为子字符串关系
  • 定义
    \uuuuu包含的类型
  • 是迭代器的类型,即定义
    \uuuu iter\uuu
  • 旧式迭代协议(依赖于
    \uuu getitem\uuu
  • 发电机分为3台

    更广泛的一点是,你真的不应该直接使用dunder方法,除非你真的理解他们在做什么。即便如此,最好还是避免这样做

    通常不值得尝试通过使用以下内容来做到可信或简洁:

    x.__lt__(y)
    
    而不是:

    x < y
    

    如果你只是天真地做一些事情,比如
    filter((1)。\uuuult\uuuuu,iterable)
    ,那么你可能有一个bug。

    Python开发人员使用他们的PEP记录他们的设计决策(和讨论),你可以在线浏览。我猜生成器是在早期的Python2中添加的,比如2.4,作为一个开始。你说的“为什么”是什么意思?似乎在生成器上的
    中,只是尝试使用它,直到它找到元素并返回True,或者生成器耗尽,在这种情况下返回False。这似乎是发电机的一种非常直观的预期行为。发电机将属于第3类,不是吗?@chepner yep,修复,谢谢
    >>> (1).__lt__(3.)
    NotImplemented
    >>>