- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
如何在类、模块上实现 __getattr__
的等价物?
当调用一个模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并在其上调用与在模块上的属性查找中失败的名称相同的方法.
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
最佳答案
您在这里遇到了两个基本问题:
__xxx__
方法只在类中查找TypeError: can't set attributes of built-in/extension type 'module'
(1) 意味着任何解决方案都必须跟踪正在检查的模块,否则 每个 模块将具有实例替换行为;和 (2) 意味着 (1) 甚至不可能......至少不是直接的。
幸运的是,sys.modules 对那里的内容并不挑剔,因此包装器将起作用,但仅用于模块访问(即 import somemodule; somemodule.salutation('world')
; 相同 -模块访问您几乎必须从替换类中提取方法并将它们添加到 globals()
或者使用类上的自定义方法(我喜欢使用 .export()
) 或使用通用函数(例如那些已经作为答案列出的函数)。要记住的一件事:如果包装器每次都创建一个新实例,而全局解决方案不是,那么您最终会得到微妙的不同行为。哦,你不能同时使用这两种方法——只能用一种。
更新
来自 Guido van Rossum :
There is actually a hack that is occasionally used and recommended: a module can define a class with the desired functionality, and then at the end, replace itself in sys.modules with an instance of that class (or with the class, if you insist, but that's generally less useful). E.g.:
# module foo.py
import sys
class Foo:
def funct1(self, <args>): <code>
def funct2(self, <args>): <code>
sys.modules[__name__] = Foo()
This works because the import machinery is actively enabling this hack, and as its final step pulls the actual module out of sys.modules, after loading it. (This is no accident. The hack was proposed long ago and we decided we liked enough to support it in the import machinery.)
因此,实现您想要的既定方法是在您的模块中创建一个类,并作为模块的最后一个 Action ,将 sys.modules[__name__]
替换为您的类的实例-- 现在您可以根据需要使用 __getattr__
/__setattr__
/__getattribute__
。
注意 1:如果您使用此功能,那么模块中的任何其他内容,例如全局变量、其他函数等,都会在 sys.modules
时丢失分配已完成——因此请确保所需的一切都在替换类中。
注意2:要支持from module import *
,你必须在类中定义__all__
;例如:
class Foo:
def funct1(self, <args>): <code>
def funct2(self, <args>): <code>
__all__ = list(set(vars().keys()) - {'__module__', '__qualname__'})
根据您的 Python 版本,__all__
中可能会省略其他名称。如果不需要兼容 Python 2,则可以省略 set()
。
关于python - __getattr__ 在模块上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2447353/
__getattr__ 可用于定义对象的属性。例如。以下代码将返回'bar'。 class Test(object): def __getattr__(self, key):
我一直在尝试实现 __getattr__ 函数,如下例所示: PEP 562 -- Module __getattr__ and __dir__ 我不明白为什么这段简单的代码: # lib.py de
读一本书,我遇到了这段代码...... # module person.py class Person: def __init__(self, name, job=None, pay=0):
我遇到了内置的 __getattr__ 并且想知道什么时候可以使用它。我很难从文档中想到实际用途 http://docs.python.org/reference/datamodel.html# .什
我正在尝试找到一种方法来设置封装到 class 中的 dict 值,例如使用 __getattr__ 我可以返回内部 dict 值,但是即使属性存在,也会调用 __setattr__,这让我的实现变得
我想在类实例化期间更改 __getattr__。例如: class AttrTest(object): def __init__(self): self.__getattr__
这个问题在这里已经有了答案: How can I intercept calls to python's "magic" methods in new style classes? (4 个答案)
我必须自定义 __getattr__ 来调用另一个函数来读取。 除了 help(object.attr) 不起作用外,这很好用。此代码用于交互式环境,因此 help() 对我们来说变得很重要。 是否有
当未找到属性时,将调用 object.__getattr__。是否有等效的方法来拦截未定义的方法? 最佳答案 没有区别。方法也是一种属性。 (但是,如果您希望该方法有一个隐式的“self”参数,您将不
我的类(class)有一个字典,例如: class MyClass(object): def __init__(self): self.data = {'a': 'v1', '
如何在类、模块上实现 __getattr__ 的等价物? 示例 当调用一个模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并在其上调用与在模块上的属性查找中失败的名称相同的方法.
如何覆盖 __getattr__一个类的方法而不破坏默认行为? 最佳答案 覆盖 __getattr__ 应该没问题 - __getattr__ 仅作为最后的手段调用,即如果实例中没有与名称匹配的属性。
感谢您花时间阅读本文。希望你在这些陌生的时刻一切都好。 我正在实现一个类并开始研究如何为其属性提供自动完成功能。从我的在线研究中,我得出的结论是 ipython 补全来自 __dir__ 方法。 __
对于 Thing 类,当我调用一个未定义的方法时,例如 .doamethod()... class Thing: def __init__(self): pass de
我有一个类,它是成员的容器。所有成员都属于同一类型。 class A(int): def __init__(self, n): super().__init__()
import random class Foo(object): def __init__(self): self._name = ''.join([chr(65 + rand
在《学习Python 3rd》中,我看到了这段代码 class wrapper: def __init__(self, object): self.wrapped = obje
在我的基于 Flask sqlalchemy 的应用程序中,我有一个这样的模型: class Foo(object): start_date = db.Column(db.DateTime()
正如标题所说。似乎无论我做什么,都不会调用 __getattr__。例如,我也尝试过(我知道这很荒谬),但不出所料没有回应。就好像 __getattr__ 在元类中被禁止了一样。 如果有任何关于此文档
这个问题在这里已经有了答案: Overriding special methods on an instance (5 个答案) 关闭 5 年前。 我现在正在从事一个项目,该项目处理抽象数学意义上的
我是一名优秀的程序员,十分优秀!