如何从 Python 中的变量定义 class 属性?

How can I define a class attribute from a variable in Python?

我需要从嵌套 class 访问变量。 objective 是使用 Marshmallow 库创建一个 Schema。代码如下所示:

class ParserScheme(Schema):

    class Meta:
        # Here I meed to access the value of my_variable :
        result = func(my_variable)

my_variable = 'foo'
my_parser = ParserScheme()

如果我设法将我的变量作为外部 class (ParserScheme) 的 class 属性传递,那么很容易将它放入内部 class (Meta) .

class ParserScheme(Schema):
    class_attribute = my_variable
    class Meta:
        result = func(ParserScheme.class_attribute)

my_variable = 'foo'
my_parser = ParserScheme()

但是我似乎找不到动态设置 class 属性的方法。如果我设置一个 "classic" 属性(我的意思是 class 实例的属性,而不是 class 本身的属性),那么我无法从内部 [=26] 访问它=].

我也想过使用全局变量,但我不太满意。还有其他方法吗?

我对 OOP 比较陌生,我不确定我是否真的理解 class 属性的概念。我担心有一种简单的方法可以做到这一点,但我没有看到它,因为我要专注于我认为这应该起作用的方式......

您的第一个示例失败,因为在执行 class Meta 语句的主体时尚未定义名称 my_variable

出于同样的原因,您的第二个示例也不会工作(my_variable 在执行 class ParserScheme 语句的主体时尚未定义),如果它在执行时仍然会中断class Meta 语句的主体,因为它将作为 class ParserScheme 语句主体的一部分执行,因此 定义名称 ParserScheme 之前。

这里你要明白的是 classdef 是可执行语句,当模块首次导入当前模块时,它们(如果在模块的顶层)按顺序执行过程。在 class 语句的情况下,语句的主体首先在专用命名空间中顺序执行,然后将此命名空间传递给 metaclass 构造函数并用于创建 class 对象的属性( YourClass.__dict__)。

长话短说:在 class 语句体中,您 不能 引用尚未在当前或封闭范围中定义的名称。时期。

这里明显的解决方案是在 class 语句之前定义 my_variable,但我假设您希望它更动态?如果是,则必须在函数中定义 class:

def create_parser_class(my_variable):

    class ParserScheme(Schema):

        class Meta:
            result = func(my_variable)


    return ParserScheme


my_variable = 42
cls = create_parser_class(my_variable)
my_parser = cls()

但我不能保证它会与 Marshmallow(我从未使用过但可能有一些 metaclass 东西正在发生)开箱即用(甚至根本无法工作)。此外,根据 my_variable 的用途,您可能需要确保没有两次调用 create_parser_class 的值与参数相同。

最后一点:您可能在这里有一个 XY problem - 当有人问如何做一些 non-obvious 或不寻常的事情时,有时就是这种情况。也许你应该编辑你的 post 来解释 "problem behind" - 也就是说,你实际上试图用这个 "solution" 解决的问题。

哦,是的:

I am rather new to OOP, and I am not sure I understand really well the concept of class attribute

在 Python 中,classes 也是对象(它们的实例 class,默认情况下是 type 对象),因此它们有自己的对象属性。您在 class 语句的 top-level 处定义的每个名称(带有赋值、def 语句、class 语句或 import 语句)成为class 对象的属性(除非自定义元 class 在途中进行了一些转换)。

Class 属性也可以从实例访问(除非被同名实例变量隐藏),并且在所有实例之间共享。