如何在Python中重写内置的getattr?

3 投票
2 回答
1869 浏览
提问于 2025-04-16 00:03

我知道怎么重写一个对象的getattr()方法,这样可以处理对未定义对象函数的调用。不过,我想让内置的getattr()函数也有同样的效果。比如,考虑下面这段代码:

   call_some_undefined_function()

通常,这段代码会直接报错:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'call_some_undefined_function' is not defined

我想重写getattr(),这样我就可以拦截对“call_some_undefined_function()”的调用,然后想办法处理这个情况。

这可能吗?

2 个回答

1

你没有说明你为什么想要这样做。我曾经有一个情况,我希望能处理我在交互式Python会话中犯的拼写错误,所以我把这个放进了我的Python启动文件里:

import sys
import re

def nameErrorHandler(type, value, traceback):
    if not isinstance(value, NameError):
        # Let the normal error handler handle this:
        nameErrorHandler.originalExceptHookFunction(type, value, traceback)
    name = re.search(r"'(\S+)'", value.message).group(1)

    # At this point we know that there was an attempt to use name
    # which ended up not being defined anywhere.
    # Handle this however you want...

nameErrorHandler.originalExceptHookFunction = sys.excepthook
sys.excepthook = nameErrorHandler

希望这对将来想要为未定义的名称设置特殊错误处理的人有帮助……至于这对提问者是否有用就不清楚了,因为他们从来没有告诉我们他们的具体用途是什么。

2

我只能想到一种方法来实现这个功能,那就是使用eval。

class Global(dict):
    def undefined(self, *args, **kargs):
        return u'ran undefined'

    def __getitem__(self, key):
        if dict.has_key(self, key):
            return dict.__getitem__(self, key)
        return self.undefined

src = """
def foo():
    return u'ran foo'

print foo()
print callme(1,2)
"""

code = compile(src, '<no file>', 'exec')

globals = Global()
eval(code, globals)

上面的代码输出了

ran foo
ran undefined

撰写回答