2010-06-16 4 views
3

Je sais comment surcharger getattr() d'un objet pour gérer les appels à des fonctions d'objet indéfini. Cependant, je voudrais atteindre le même comportement pour la fonction getattr() intégrée. Par exemple, considérons le code comme ceci:Comment remplacer le getattr intégré en Python?

call_some_undefined_function() 

Normalement, qui produit une simple erreur:

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

Je veux passer outre getattr() pour que je puisse intercepter l'appel à "call_some_undefined_function()" et devinez quoi faire.

Est-ce possible?

+0

L'objet module a une méthode '__getattribute__', mais il n'est apparemment pas utilisé. – Omnifarious

+2

Une question: Pourquoi? –

+1

pour quoi avez-vous besoin de cela? Oo – Joschua

Répondre

2

Je ne peux penser à un moyen de le faire en appelant 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) 

Les sorties au-dessus

ran foo 
ran undefined 
0

Vous ne l'avez pas dit pourquoi vous essayez de le faire. J'ai eu un cas d'utilisation où je voulais être capable de gérer les fautes de frappe que j'ai fait au cours des sessions de Python interactif, donc je mets ceci dans mon fichier de démarrage 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 

Espérons que cela est utile pour tout le monde à l'avenir qui veut avoir un gestionnaire d'erreur spécial pour les noms non définis ... si cela est utile pour l'OP ou non est inconnu, car ils ne nous ont jamais dit quel était leur cas d'utilisation prévu.

Questions connexes