使用 [object instance].__self__ 有什么意义?

asd*_*van 40 python

groupby我正在检查Python中toolz库函数的代码,我发现了这个:

def groupby(key, seq):
    """ Group a collection by a key function
    """
    if not callable(key):
        key = getter(key)
    d = collections.defaultdict(lambda: [].append)
    for item in seq:
        d[key(item)](item)
    rv = {}
    for k, v in d.items():
        rv[k] = v.__self__
    return rv
Run Code Online (Sandbox Code Playgroud)

有什么理由使用rv[k] = v.__self__而不是rv[k] = v

Meg*_*Ing 40

这是一个有点令人困惑的技巧,可以节省少量时间:

我们正在创建一个带有工厂函数的工厂函数,该函数返回带有 的新列表实例的defaultdict绑定方法。然后我们就可以这样做,而不是像创建一个包含列表的那样。如果我们不每次都查找,我们就会赢得一点时间。append[].appendd[key(item)](item)d[key(item)].append(item)defaultdictappend

但现在dict包含绑定方法而不是列表,因此我们必须通过 获取原始列表实例__self__

__self__是为返回原始实例的实例方法描述的属性。您可以使用以下示例验证这一点:

>>> a = []
>>> a.append.__self__ is a
True
Run Code Online (Sandbox Code Playgroud)

  • @donttalkjustcode 我坚持这一点。它不是可以在这里使用的最清晰的代码(但它也不是他们可以选择的最令人困惑的变体)。IMO,任何需要对 SO 提出一个不可怕的问题来解释它的东西都可以被归类为令人困惑的。 (10认同)
  • @不要说话只是代码。我必须查找“__self__”,以前从未使用过它。一旦我做到了,这就是微不足道的,并且将来可能仍然如此。这是一个经验问题。 (3认同)

Mad*_*ist 18

这是一种有点复杂但可能更有效的创建和使用defaultdict

首先,请记住默认项目是lambda: [].append。这意味着创建一个新列表,并将绑定append方法存储在字典中。这可以节省您在每次进一步追加到同一键时的方法绑定,以及随后的垃圾收集。例如,以下更标准的方法效率较低:

d = collections.defaultdict(list)
for item in seq:
    d[key(item)].append(item)
Run Code Online (Sandbox Code Playgroud)

那么问题就变成了如何从字典中获取原始列表,因为引用没有显式存储。幸运的是,绑定方法有一个__self__属性可以做到这一点。这里,[].append.__self__是对原文的引用[]

作为旁注,最后一个循环可能是一个理解:

return {k: v.__self__ for k, v in d.items()}
Run Code Online (Sandbox Code Playgroud)