2016-04-09 5 views
4

Um zu Python 3 überzugehen, versuche ich, Python 2 und Python 3 kompatible Codes zu schreiben. Der folgende Code stammt von python-future.org und veranschaulicht eine Möglichkeit, einen Iterator zu erstellen, der mit beiden Versionen von Python kompatibel ist.In Python, warum "Objekt" aus dem eingebauten Modul importieren?

from builtins import object 

class Upper(object): 
    def __init__(self, iterable): 
     self._iter = iter(iterable) 
    def __next__(self):  # Py3-style iterator interface 
     return next(self._iter).upper() # builtin next() function calls 
    def __iter__(self): 
     return self 

itr = Upper('hello') 
assert next(itr) == 'H'  # compatible style 
assert list(itr) == list('ELLO') 

Der Code läuft gut in Python 2, aber zu meiner Überraschung, wenn ich die Import-Anweisung entferne dann bekomme ich einen Fehler TypeError: Upper object is not an iterator. Ich leite oft meine benutzerdefinierten Klassen von object ab, aber ich habe es nie von eingebauten importiert. Warum ändert einfach das Importieren des Codes object das Verhalten?

+3

In Python 2 müssen 'Builtins 'installiert werden. Es ist für das Schreiben von Code kompatibel auf Python 2 und 3 konzipiert. –

+0

Wenn * I * diesen Code in Python 2 ausführen, bekomme ich 'ImportError: Kein Modul namens builtins'. Es gibt * ein Modul mit dem Namen '__builtin__', und ich kann 'von__builtin__ import object', aber es macht keinen Unterschied, ich bekomme den' TypeError: Oberes Objekt ist kein Iterator'. Das macht Sinn, denn in Python 2 implementieren Sie 'next', nicht' __next__', um ein Iterator zu sein. Ich denke, das Codebeispiel, das Sie gerade lesen, ist einfach falsch. Könnten Sie bitte einen direkten Link dazu schreiben? Bitte teilen Sie uns auch genau mit, welche Versionen von Python 2 und 3 Sie testen. – zwol

+0

Also gibt es einen Unterschied zwischen dem '' Objekt'', das im Standard-Namespace verfügbar ist und dem, der von '' builtins'' importiert wird? – deepak

Antwort

9

Sie importieren (indirekt) von der future.builtins module; Es bietet eine benutzerdefinierteobject Basisklasse, die nach vorne zeigende spezielle Namen hinzufügt. In Python 2 müssen Iteratoren eine next() method (sowie __iter__) haben; Diese Methode wurde in __next__ in Python 3 umbenannt. Durch den Verzicht auf die future.builtins.object Version verwenden sind Sie nicht einfach die next ->__next__ alias in Python zur Verfügung gestellt 2.

Siehe source code for future.types.newobject.py:

def next(self): 
    if hasattr(self, '__next__'): 
     return type(self).__next__(self) 
    raise TypeError('newobject is not an iterator') 

Beachten Sie, dass builtins kehrt integrierten Standard-Objekte, wenn Sie laufen Python 3, kehrt das Modul nur Beilagen wie diese für Python 2.

Sie einfach das gleiche Alias ​​selbst hinzufügen könnte:

class Upper(object): 
    def __init__(self, iterable): 
     self._iter = iter(iterable) 

    def __iter__(self): 
     return self 

    def __next__(self):  # Py3-style iterator interface 
     return next(self._iter).upper() # builtin next() function calls 
    next = __next__   # Py2 alias 
+2

Ah! Ich wusste nicht, dass das '' builtins' 'Modul aus der Zukunft stammte ..... – deepak

Verwandte Themen