魔术方法和定义顺序

Magic methods and definition order

我正在查看 trie implementation

的源代码

第 80-85 行:

def keys(self, prefix=[]):
    return self.__keys__(prefix)

def __keys__(self, prefix=[], seen=[]):
    result = []
    etc.
  1. 什么是def __keys__那是自创的魔法物品吗?如果是这样,这是糟糕的代码吗?或者 __keys__ 是否作为标准 Python 魔法方法存在?不过,我在 Python 文档中找不到它。

  2. 为什么在 def __keys__ 实例化之前函数调用 self.__keys__ 是合法的? 不会 def __keys__ 必须在 def keys 之前(因为 keys 调用 __keys__)?

class 在 Python 中的编译在实例化 class 之前完成。

每当创建 class 类型时,都会编译并执行 class 块的主体。然后,所有函数都被转换为绑定句柄(普通函数)或 classmethod/staticmethod 对象。然后,当创建一个新实例时,类型 __dict__ 的内容被复制到该实例(并且绑定句柄被转换为方法)。

因此,在调用instance.keys()的那一刻,实例已经同时拥有keys__keys__方法。

另外,据我所知,在任何数据模式下都没有__keys__方法。

对于你的第二个问题,这是合法的,class 的函数是在 class 定义时定义的,所以你可以确定这两个函数都会在 [=11= 之前定义] 被调用,逻辑也适用于普通函数,我们可以做 -

>>> def a():
...     b()
...
>>> def b():
...     print("In B()")
...
>>> a()
In B()

这是合法的,因为 a()b() 都是在调用 a() 之前定义的。只有在 b() 被定义之前尝试调用 a() 才会是非法的。请注意,定义一个函数不会自动调用它,并且 python 在定义函数时不会验证函数中使用的任何函数是否已定义(直到运行时,当函数被调用时,在这种情况下它抛出一个 NameError)

关于你的第一个问题,我不知道有什么叫做 __keys__() 的魔术方法,也无法在文档中找到它。

所有真实的"magic methods"都在data model documentation; __keys__ isn't one of them. The style guide说:

Never invent such names; only use them as documented.

所以是的,组成一个新的形式是不好的形式(惯例是称它为 _keys)。

你问题的第二部分没有意义;即使这不是 class,也无需按照调用顺序定义方法和函数。只要它们存在 实际进行调用时,这就不是问题。我倾向于在私有方法之前定义 public 方法,即使前者可能调用后者,只是为了 reader 的方便。

  1. 没有名为 __keys__() 的魔术方法,因此您怀疑这只是糟糕的命名。

  2. class定义中的代码可以任意顺序。到下游实际调用时已经定义的所有事项。

没有名为__keys__的魔术方法,所以它只是一个错误的命名约定。看代码,作者只是想有一个内部使用的private方法,也来自public方法keys。如您所见,__keys__ 接受一个附加参数。

关于第二个问题,你没有必要按照函数调用的顺序定义函数。它将在编译代码时可用。