为什么类定义需要比函数定义中需要的更多属性信息?

Why class definition needs more information of its attributes than what is needed in a function definition?

提问人:Youjun Hu 提问时间:2/12/2022 最后编辑:Youjun Hu 更新时间:2/12/2022 访问量:36

问:

def myfunc():
    return x
x = 10
print(myfunc())

上面的代码是有效的,当我定义 .xmyfunc

但是,以下代码不起作用:

class myclass:
   func = extfunc

def extfunc(self):
    return 'hello'

在这里,我需要将 的定义移到类定义之前,以使代码正常工作。extfunc

为什么类定义需要比函数定义中自由变量所需的属性信息更多的信息?

Python 作用域 命名空间

评论

6赞 deceze 2/12/2022
因为函数的主体在调用时是计算的,但类定义的主体是在类定义时计算的,因为否则你将如何定义类?
0赞 Youjun Hu 2/12/2022
有没有可能存在类定义足够灵活的语言,以至于在实例化类实例之前不需要完全确定类定义?
1赞 deceze 2/12/2022
那么,如何定义类属性和方法呢?你基本上可以通过将内容移动到 中来做到这一点,但对于每个实例来说,拥有自己的方法版本是低效的。__init__

答:

2赞 T.J. Crowder #1

此代码:

def myfunc():
    return x

定义一个函数,但不执行其中的代码,直到/除非被调用。在计算函数定义时,不会计算函数的主体,稍后在调用函数时计算xmyfunc

相比之下,在此代码中:

class myclass:
    func = extfunc

为了创建类,将评估类定义,如此处的文档中所述。因此,作为类定义的一部分进行计算,以便为类作用域中的变量赋值。 就像使用该术语的语言中的静态成员一样。func = extfuncfuncfunc

一个更直接的比较是这样的:

class myclass:
    def example(self):
        return x

在那里,直到或除非被调用,否则不会进行评估。return xexample

另请参阅文档中的此示例

属性引用使用用于 Python 中所有属性引用的标准语法:。有效属性名称是创建类对象时类命名空间中的所有名称。因此,如果类定义如下所示:obj.name

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

then 和 是有效的属性引用,分别返回一个整数和一个函数对象。MyClass.iMyClass.f

在您的示例中,将是紧跟在类定义之后的有效引用,因此必须在类定义期间进行计算,这与函数的主体不同。myclass.funcfunc = extfunc