代码之家  ›  专栏  ›  技术社区  ›  myol

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

  •  2
  • myol  · 技术社区  · 7 年前

    我不明白为什么会这样;

    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 回复  |  直到 7 年前
        1
  •  2
  •   gilch    7 年前

    类在执行时似乎是逐行读取的,如果方法定义在属性中被引用之前没有被解析,会发生错误吗?

    是的,那是真的。类定义从上到下执行,就像模块级代码一样。甚至可以将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()
    

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

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

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

    上课只是花哨的听写。您可以在运行时交换属性。当你做一个 self.foo() 方法内部 bar ,的 . 运算符正在执行的属性查找 foo 属性 self 对象。使用时也有类似的想法 cls.foo() 在类方法中。

    完全可以编写一个引用不存在的属性的函数。它将失败 AttributeError 当然,如果您调用它,但是如果稍后某个属性被设置,那么您可以成功地调用它。

    推荐文章