【问题标题】:Are dunders methods or functions? [duplicate]dunders 是方法还是函数? [复制]
【发布时间】:2020-11-22 15:13:11
【问题描述】:

我对使用__iter__()__next__() 之类的方法有点困惑(我想它们被称为dunders)。 我试图理解迭代器和可迭代对象并编写了以下代码:

x = (1, 2, 3, 4, 5, 6)
try:
    y = x.__iter__()
    while 1:
        print(y.__next__())
except StopIteration:
    print('Iterator has exhausted')

然后当我使用__iter____next__ 作为函数时,代码得到执行而没有错误:

x = (1, 2, 3, 4, 5, 6)
try:
    y = iter(x)
    while 1:
        print(next(y))
except StopIteration:
    print('Iterator has exhausted')

谁能告诉我如何将它们用作方法和函数?它适用于所有的dunders吗?

【问题讨论】:

  • iter and next 是函数。 __iter__ and __next__ 是方法。
  • 所以你的意思是, __iter__() 和 __next__() 是对象元组的方法(这里)和 next() 和 iter() 是内置函数。而这对其他笨蛋来说不是真的吗?
  • “这件事对其他笨蛋来说不是真的吗?”是什么让你做出这样的推断?所有 dunder 都为每个支持它们的类提供了单独的实现,整个相关的内置函数只为所有类型实现一次。
  • 您不应该真正调用魔术方法,这就是为什么它们可能或可能不适用于内置类型。然而,第二个变体中的iter(x) 确实为您提供了一个迭代器,因此您可以使用y.__next__()
  • @tevemadar 你在那里自相矛盾!一旦你调用了y = iter(x),你就会想调用next (y),而不是y.__next()__

标签: python python-3.x magic-methods


【解决方案1】:
  • 如果您正在编写自己的类并希望它支持被迭代,那么请为它编写一个__iter__ 方法。
  • 如果您使用支持迭代的类,请调用 iter 函数(或者,在大多数情况下,您不需要太多控制,只需在 for 循环中使用它即可)。

这不仅适用于这对特定的配对,还适用于其他 dunder 方法和相关功能,例如len()__len__()

在底层,iter 函数只是调用传递给它的对象的__iter__ 方法。你可能会问:那为什么还要费心有一个iter 函数,你可以自己调用__iter__ 方法呢? (也许这就是你真正想知道的。)我能想到的原因有两个:

  • 如果您调用不带下划线的函数,它会使您的代码看起来更整洁。
  • 通常使用这对内置函数和相关的 dunder 方法,内置函数实际上会处理一些不同的细节。 iter 就是一个例子:正如 docs 所说,它不仅适用于具有 __iter__ 方法的类型,而且适用于满足容器协议的类型(即 __len____getitem__ 方法)。
  • (此外,这些下划线表示您不打算直接调用该方法,但是当您已经在询问为什么不直接调用它们时,这种解释有点循环。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 2015-05-23
    • 2012-02-22
    • 2013-09-07
    • 2017-04-07
    • 2012-06-21
    • 2014-04-11
    相关资源
    最近更新 更多