[英]Python's importlib and inspect for static class members
In a long-running app I need to dynamically modify static class members based on path to the class' module and the class name.在长时间运行的应用程序中,我需要根据类模块的路径和类名动态修改静态类成员。
Ex.前任。 I have a class pack1.mod1.Person
and by definition I know it has a age
property.我有一个类pack1.mod1.Person
并且根据定义我知道它有一个age
属性。 So utilizing the importlib
and inspect
I try to load the class using the module path and class name and update the age
property.因此,利用importlib
和inspect
我尝试使用模块路径和类名加载类并更新age
属性。 It all seems fine until I read the the age
property from my naturally imported Person
class and find it's not updated.一切似乎都很好,直到我从我自然导入的Person
类中读取了age
属性并发现它没有更新。
Here are some more details:以下是更多详细信息:
.
├── app.py
└── pack1
├── __init__.py
└── mod1.py
mod1.py模块1.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
In the app.py
I would expect member
and Person
to be the same thing but as the example shows they aren't.在app.py
我希望member
和Person
是同一件事,但正如示例所示,它们不是。
What am I missing and how to achieve such an update on the static members of a class?我错过了什么以及如何对类的静态成员进行这样的更新?
Python has no way of knowing that the regularly imported module and the manually module are "the same": Using util.spec_from_file_location
up to spec.loader.exec_module
side-steps Python's module registry and explicitly creates a new instance of the module. Python 无法知道定期导入的模块和手动模块是“相同的”:使用util.spec_from_file_location
到spec.loader.exec_module
Python 的模块注册表并显式创建模块的新实例。
Instead, use the native operations of the interpreter ( import
, ...) or their programmatic equivalents ( importlib.load_module
, ...)相反,使用解释器的本机操作( import
,...)或其编程等效项( importlib.load_module
,...)
If the module/class are well-known, one can import
it regularly and directly inspect it.如果模块/类是众所周知的,可以定期import
并直接检查它。
import pack1.mod1
pack1.mod1.Person.age = 66
If module and class are only known by name, one can look them up from the existing modules.如果模块和类仅通过名称知道,则可以从现有模块中查找它们。
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}`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.