Python的importlib和inspect的静态类成员

2024-04-16 06:12:24 发布

您现在位置:Python中文网/ 问答频道 /正文

在长时间运行的应用程序中,我需要根据类的模块路径和类名动态修改静态类成员

我有一个类pack1.mod1.Person,根据定义我知道它有一个age属性。因此,利用importlibinspect,我尝试使用模块路径和类名加载类,并更新age属性。在我从自然导入的Person类中读取age属性并发现它没有更新之前,一切似乎都很好

以下是一些更详细的信息:

.
├── app.py
└── pack1
    ├── __init__.py
    └── mod1.py

mod1.py

class Person:
    age = 42

app.py

import inspect
import os
from importlib import util

from pack1.mod1 import Person

if __name__ == '__main__':
    Person.age = 3
    print(Person.age)  # => 3

    spec = util.spec_from_file_location('pack1.mod1', os.path.join('pack1', 'mod1.py'))
    module = util.module_from_spec(spec)
    spec.loader.exec_module(module)

    members = inspect.getmembers(module)

    for x, member in inspect.getmembers(module, lambda i: inspect.isclass(i) and i.__name__ == Person.__name__):
        print('Person:', Person.age)  # => Person: 3
        print('Person from inspect:', member.age)  # => Person from inspect: 42
        Person.age = 11
        member.age = 66
        print('Person:', Person.age)  # => Person: 11
        print('Person from inspect:', member.age)  # => Person from inspect: 66

app.py中,我希望memberPerson是相同的东西,但正如示例所示,它们不是

我缺少什么?如何在类的静态成员上实现这样的更新


Tags: frompyimportappage属性utilperson
1条回答
网友
1楼 · 发布于 2024-04-16 06:12:24

Python无法知道定期导入的模块和手动导入的模块是“相同”的:使用util.spec_from_file_locationspec.loader.exec_module端的步骤执行Python的模块注册表,并显式创建模块的新实例。
相反,使用解释器的本机操作(import,…)或它们的编程等价物(importlib.load_module,…)

如果模块/类是众所周知的,可以定期检查它并直接检查它

import pack1.mod1
pack1.mod1.Person.age = 66

如果只知道模块和类的名称,则可以从现有模块中查找它们

import importlib

module_name, qualname, attribute, value = 'pack1.mod1', 'Person', 'age', 66

obj = importlib.import_module(module_name)  # same as `import {module_name}`
for part in qualname.split('.'):
    obj = getattr(obj, part)                # same as `{obj}.{part}

setattr(obj, attribute, value)              # same as `{obj}.{attribute} = {value}`

相关问题 更多 >