定义方法前属性中的方法引用会导致错误

时间:2018-11-26 05:26:06

标签: python python-3.x class attributes

我不明白为什么会这样;

class parentClass(object):
    pass

class childClass(parentClass):

    def my_meth(var):
        print(var)

    a = {'meth': my_meth}

x = childClass.a['meth']("Helloworld")

这失败了;

class parentClass(object):
    pass

class childClass(parentClass):

    a = {'meth': my_meth}

    def my_meth(var):
        print(var)

x = childClass.a['meth']("Helloworld")

似乎会在执行时逐行读取一个类,如果在属性中引用该方法定义之前尚未解析方法定义,会发生错误吗?

这是真的吗?为什么会在类/静态属性中发生这种情况,而您却可以按任何顺序定义方法并从上面或下面编写的其他方法中引用它们?

是否有一种方法可以将类属性保留在类的顶部,以保持可读性和一致的布局?

1 个答案:

答案 0 :(得分:2)

  

似乎是在执行时逐行读取一个类,并且如果在属性中引用该方法定义之前尚未解析方法定义,是否会发生错误?

是的,是的。类定义从上到下执行,就像模块级代码一样。您甚至可以将if / else语句和for循环之类的内容直接放在类主体中。

  

是否有一种方法可以将类属性保留在类的顶部,以保持可读性和一致的布局?

您的第一个示例很好。该顺序在Python中并不奇怪。

也就是说,您确实有其他选择。例如,您可以创建一个@classmethod来初始化类顶部的类属性,然后在类声明后立即调用,例如

class childClass(parentClass):

    @classmethod
    def _initialize(cls)
        cls.a = {'meth': cls.my_meth}

    def my_meth(var):
        print(var)

childClass._initialize()

您甚至可以编写一个类装饰器来为您执行此步骤(如果您认为这更漂亮),因为它们在类声明代码完成执行之后执行。

  

为什么这会在类/静态属性中发生,而您却可以按任何顺序定义方法并从上面或下面编写的其他方法中引用它们呢?

执行功能定义与调用其创建的功能 object 不同。前者只是创建函数对象,并将其名称分配给本地上下文。后者运行其代码。

课堂只是幻想。您可以在运行时将属性交换进出。当您在方法self.foo()中执行bar时,.运算符正在对foo对象上的self属性进行属性查找。在类方法中使用cls.foo()时,这是一个类似的想法。

完全有可能编写一个引用不存在的属性的函数。当然,如果您调用AttributeError,它将失败,但是如果稍后以某种方式设置了属性,则可以成功调用它。