2010-06-16 5 views
3

Я знаю, как переопределить getattr() объекта для обработки вызовов неопределенным объектным функциям. Тем не менее, я хотел бы добиться такого же поведения для встроенной функции getattr(). Например, рассмотрим такой код:Как переопределить встроенный getattr в Python?

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()» и выяснить, что делать.

Возможно ли это?

+0

Объект модуля имеет метод '__getattribute__', но он, по-видимому, не используется. – Omnifarious

+2

Один вопрос: почему? –

+1

Зачем вам это нужно? Oo – Joschua

ответ

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 
0

Вы не сказали, почему вы пытаетесь это сделать. У меня был случай, когда использование я хотел быть способны обрабатывать опечатки, которые я сделал во время интерактивных сессий 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 

Надеется, что это полезно для тех, кто в будущем, кто хочет иметь специальный обработчик ошибок для неопределенных имен ... независимо от того, является ли это полезным для OP или нет, неизвестно, так как они на самом деле никогда не говорили нам, каков их предназначенный вариант использования.

Смежные вопросы