TL;DR: Is globals()[name]
the CORRECT way to fall back to the "default"?
I have a large set of dynamically created classes that are defined from a YML file.
Dynamic class creation is accomplished via a combination of PyYAML yaml.safe_load_all
and the dataclasses.make_dataclass
(new in 3.7). I expect the specifications for these classes to occasionally change over time, which is why I chose YML as an easily understood format to describe them.
Python 3.7 is introducing new functionality (see PEP 562): a module-level __getattr__
function for managing module attribute access (there is also a module-level __dir__
function). It would be convenient to utilize this new function to allow importing of each dynamically created dataclass
class from the module namespace, like so:
# some_module.py
from package_name import DataClassName1, DataClassName2
...and like so:
# package_name/__init__
from .my_dataclasses import DynamicDataClassesDict
def __getattr__(name):
try:
return DynamicDataClassesDict[name]
except KeyError:
# fall back on default module attribute lookup
In reading PEP 562 it isn't immediately clear to me how to fall back to default functionality for module attribute access. For a class, one would just call super().__getattr__(*args)
. I do see this line in one of the examples:
return globals()[f"_deprecated_{name}"]
This approach seems to work. Is globals()[name]
the CORRECT way to fall back to the "default"? It doesn't seem to be, given that globals()[name]
will raise a KeyError
rather than the expected AttributeError
.