__getattr__ 在模块上 [英] __getattr__ on a module
问题描述
如何在类、模块上实现与 __getattr__
等效的代码?
How can implement the equivalent of a __getattr__
on a class, on a module?
当调用模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并使用与模块的属性查找失败相同的名称调用该类的方法.
When calling a function that does not exist in a module's statically defined attributes, I wish to create an instance of a class in that module, and invoke the method on it with the same name as failed in the attribute lookup on the module.
class A(object):
def salutation(self, accusative):
print "hello", accusative
# note this function is intentionally on the module, and not the class above
def __getattr__(mod, name):
return getattr(A(), name)
if __name__ == "__main__":
# i hope here to have my __getattr__ function above invoked, since
# salutation does not exist in the current namespace
salutation("world")
给出:
matt@stanley:~/Desktop$ python getattrmod.py
Traceback (most recent call last):
File "getattrmod.py", line 9, in <module>
salutation("world")
NameError: name 'salutation' is not defined
推荐答案
不久前,Guido 声明所有特殊方法查找都在新式类绕过 __getattr__
和 __getattribute__
.Dunder 方法以前适用于模块 - 例如,在使用这些技巧之前,您可以简单地通过定义 __enter__
和 __exit__
将模块用作上下文管理器坏了.
A while ago, Guido declared that all special method lookups on
new-style classes bypass __getattr__
and __getattribute__
. Dunder methods had previously worked on modules - you could, for example, use a module as a context manager simply by defining __enter__
and __exit__
, before those tricks broke.
最近一些历史特性卷土重来,其中包括 __getattr__
模块,以及现有的 hack(一个模块用 sys.modules
中的类替换自身导入时间)应该不再需要.
Recently some historical features have made a comeback, the module __getattr__
among them, and so the existing hack (a module replacing itself with a class in sys.modules
at import time) should be no longer necessary.
在 Python 3.7+ 中,您只需使用一种显而易见的方法.要自定义模块上的属性访问,请在模块级别定义一个 __getattr__
函数,该函数应接受一个参数(属性名称),并返回计算值或引发 AttributeError
:
In Python 3.7+, you just use the one obvious way. To customize attribute access on a module, define a __getattr__
function at the module level which should accept one argument (name of attribute), and return the computed value or raise an AttributeError
:
# my_module.py
def __getattr__(name: str) -> Any:
...
这也将允许挂钩到from"导入,即您可以为诸如 from my_module import nothing
之类的语句返回动态生成的对象.
This will also allow hooks into "from" imports, i.e. you can return dynamically generated objects for statements such as from my_module import whatever
.
在相关说明中,除了模块 getattr,您还可以在模块级别定义一个 __dir__
函数来响应 dir(my_module)
.有关详细信息,请参阅 PEP 562.
On a related note, along with the module getattr you may also define a __dir__
function at module level to respond to dir(my_module)
. See PEP 562 for details.
这篇关于__getattr__ 在模块上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!