Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In python, why import 'object' from builtins module?

Tags:

In order to transition to python 3, I am trying to understand writing python 2 and python 3 compatible codes. The following code is from python-future.org and illustrates a way to construct an iterator that would be compatible with both versions of python.

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')

The code runs fine in python 2, but to my surprise, if i remove the import statement then i get an error TypeError: Upper object is not an iterator. I often derive my custom classes from object but i have never imported it from builtins. Why does simply importing object change the behaviour of the code?

like image 501
deepak Avatar asked Apr 09 '16 13:04

deepak


People also ask

What is Builtins object in Python?

The builtins module is automatically loaded every time Python interpreter starts, either as a top level execution environment or as interactive session. The Object class, which happens to be the base class for all Python objects, is defined in this module.

What does importing a module do in Python?

The import statement allows you to import one or more modules into your Python program, letting you make use of the definitions constructed in those modules.

What is __ import __ in Python?

__import__() . This means all semantics of the function are derived from importlib. __import__() . The most important difference between these two functions is that import_module() returns the specified package or module (e.g. pkg. mod ), while __import__() returns the top-level package or module (e.g. pkg ).

Where is the Builtins Python?

UPDATE You can find builtins module's code in Python/bltinmodule. c from the Python source code.


1 Answers

You are (indirectly) importing from the future.builtins module; it provides a custom object baseclass that adds forward-pointing special names.

In Python 2, iterators must have a next() method (as well as __iter__); this method was renamed to __next__ in Python 3. By not using the future.builtins.object version you are simply missing the next -> __next__ alias provided in Python 2.

See the 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')

Note that builtins will return standard built-in objects if you are running Python 3, the module only returns shims like these for Python 2.

You could simply add that same alias yourself:

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
like image 80
Martijn Pieters Avatar answered Sep 18 '22 05:09

Martijn Pieters