Ric*_*ica 1 python attributes module python-3.7
TL; DR:globals()[name]CORRECT 是否可以回归到"默认"?
我有一大堆动态创建的类,它们是从YML文件定义的.
动态类创建是通过PyYAMLyaml.safe_load_all和dataclasses.make_dataclass(3.7中的新增功能)的组合完成的.我希望这些类的规范偶尔会随着时间而改变,这就是为什么我选择YML作为一种易于理解的格式来描述它们.
Python 3.7引入了新功能(参见PEP 562):__getattr__用于管理模块属性访问的模块级__dir__功能(还有一个模块级功能).利用这个新函数可以方便地dataclass从模块名称空间导入每个动态创建的类,如下所示:
# some_module.py
from package_name import DataClassName1, DataClassName2
Run Code Online (Sandbox Code Playgroud)
......并且像这样:
# package_name/__init__
from .my_dataclasses import DynamicDataClassesDict
def __getattr__(name):
try:
return DynamicDataClassesDict[name]
except KeyError:
# fall back on default module attribute lookup
Run Code Online (Sandbox Code Playgroud)
在阅读PEP 562时,我不清楚如何回退到模块属性访问的默认功能.对于一个班级,人们只会打电话super().__getattr__(*args).我确实在其中一个例子中看到了这一行:
return globals()[f"_deprecated_{name}"]
Run Code Online (Sandbox Code Playgroud)
这种方法似乎有效.是globals()[name]回落到"默认"的正确方法?它似乎并不是,因为它globals()[name]会提高KeyError而不是预期AttributeError.
你倒退了.模块级__getattr__函数仅作为最后的手段调用.没有什么可以回溯 - 所有其他机制都已经找不到该名称的属性.
例如,如果您的模块定义了一个全局foo变量并且有人访问your_module.foo,则__getattr__甚至不会被调用.
PEP在规范中解释了这一点:
如果通过正常查找(即
object.__getattribute__)在模块对象上找不到属性,则在引发AttributeError之前__getattr__在模块中搜索__dict__该属性.
因此,正确的"回退行为"是引发AttributeError.