魔术方法和定义顺序

时间:2015-08-07 06:59:57

标签: python trie magic-methods

我正在查看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. 为什么函数在self.__keys__被实例化之前调用def __keys__是合法的? def __keys__之前不会{ {1}}(自def keys调用keys)?

5 个答案:

答案 0 :(得分:2)

对于第二个问题,它是合法的,类的函数是在定义类时定义的,因此可以确保在调用keys()之前定义两个函数,逻辑也适用于正常功能,我们可以做 -

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

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

对于你的第一个问题,我不知道任何这种称为__keys__()的魔法方法,也无法在文档中找到它。

答案 1 :(得分:2)

所有真正的"魔术方法" 都在data model documentation; _keys不是其中之一。 style guide说:

  

永远不要发明这样的名字;只能按照文件记录使用它们。

所以是的,组成一个新形式是一种糟糕的形式(惯例就是称它为{{1}})。

你问题的第二部分没有意义;即使这不是一个类,也没有必要按照它们被调用的顺序定义方法和函数。只要它们在实际调用时存在 ,它就不是问题。我倾向于在私人方法之前定义公共方法,即使前者可能称之为后者,只是为了方便读者。

答案 2 :(得分:0)

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

  2. 类定义中的代码可以按任何顺序排列。所有这些事情都是在下游进行实际调用时做出的。

答案 3 :(得分:0)

没有名为__keys__的魔术方法,所以它只是一个错误的命名约定。查看代码,作者只想拥有一个内部使用的私有方法,也可以使用公共方法keys。正如您所看到的,__keys__接受了另一个参数。

关于第二个问题,您无需按照调用的顺序定义函数。它将在编译时编码时可用。

答案 4 :(得分:-1)

在实例化类之前,在Python中编译类是完成的。

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

因此,在调用instance.keys()时,该实例已同时具有keys__keys__方法。

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