一尘不染

Python-__getattr__在模块上

python

如何__getattr__在模块上的类上实现等价于a 的等效项?


当调用模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并使用与该模块上的属性查找失败相同的名称调用该方法。

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

阅读 439

收藏
2020-02-22

共1个答案

一尘不染

你在这里遇到两个基本问题:

  1. __xxx__ 方法只在类上查找
  2. TypeError: can't set attributes of built-in/extension type 'module'
    (1)意味着任何解决方案还必须跟踪正在检查的模块,否则每个模块将具有实例替换行为;(2)表示(1)甚至是不可能的……至少不是直接的。

幸运的是,sys.modules对那里发生的事情并不挑剔,因此可以使用包装器,但是只能用于模块访问(即import somemodule; somemodule.salutation('world'),对于同模块访问,你几乎必须从替换类中提取方法并将其添加到globals()eiher中。类上的自定义方法(我喜欢使用.export())或泛型函数(例如已经列出的答案)要记住的一件事:如果包装器每次都在创建一个新实例,而全局解决方案不是,最终,你会得到完全不同的行为。哦,你不能同时使用两者-一种是另一种。

2020-02-22