2017-02-14 1 views
2

Mein Skript läuft in eine rekursive Schleife auf Python3 python3, ich habe versucht, iteritems mit items ersetzt aber nicht das Problem beheben, läuft Python2 fein .. gibt es eine Änderung __getattribute__ Ich bin nicht bewusst?Umwandlung python2 getAttribute

class Map(object):  
    def __init__(self, *args, **kwargs): 
     for arg in args: 
      if isinstance(arg, dict): 
       for k, v in arg.items(): 
        self.__dict__[k] = v 
        self.__dict__['_' + k] = v 

     if kwargs: 
      for k, v in kwargs.items(): 
       self.__dict__[k] = v 
       self.__dict__['_' + k] = v 

    def __getattribute__(self, attr): 
     if hasattr(self, 'get_' + attr): 
      return object.__getattribute__(self, 'get_' + attr)() 
     else: 
      return object.__getattribute__(self, attr) 

    def get(self, key): 
     try: 
      return self.__dict__.get('get_' + key)() 
     except (AttributeError, TypeError): 
      return self.__dict__.get(key) 


Map(**{'hello': 'world', 'foo': 'bar'}) # infinite recursion 

Wenn er gestartet wird, erzeugt dies:

Traceback (most recent call last): 
    File "demo.py", line 29, in <module> 
    Map(**{'hello': 'world', 'foo': 'bar'}) # recursive loop 
    File "demo.py", line 13, in __init__ 
    self.__dict__[k] = v 
    File "demo.py", line 17, in __getattribute__ 
    if hasattr(self, 'get_' + attr): 
    File "demo.py", line 17, in __getattribute__ 
    if hasattr(self, 'get_' + attr): 
[...] 
RecursionError: maximum recursion depth exceeded 
+0

Können Sie einen Testcode angeben, der Ihr Problem reproduziert? – cdarke

+0

@cdarke scheint es hasattr (self, 'get_' + attr): verursacht das Problem in PY3, das durch try/except-Klausel mit AttributeError behoben wird – pietklerks

Antwort

0

Sie haben hier eine unendliche Rekursion, weil Ihr __getattribute__ ruft hasattr() welche the documentation Werke Staaten von getattr() Aufruf (also Ihre Klasse __getattribute__ Aufruf).

Sie dürfen hasattr() nicht in Ihrem __getattribute__ anrufen.

Die documentation for __getattribute__ Noten dieses Potential für eine unendliche Rekursion und gibt Hinweise auf die Lösung:

Um eine unendliche Rekursion in diesem Verfahren zu vermeiden, sollte ihre Umsetzung immer die Basisklasse Methode mit dem gleichen Namen, den Zugang rufen alle Attribute, die es benötigt, z. B. Objekt. getattribute (selbst, Name).