Search code examples
pythonpython-3.xclassinstance-methods

Python Class: function or instance method


I'm learning Python with a textbook called Introduction to Computation and Programming Using Python, in Chapter 8 there is an example code:

class IntSet(object):
    """An intSet is a set of integers"""
    # Information about the implementation (not the abstraction)
    # The value of the set is represented by a list of ints, self.vals.
    # Each int in the set occurs in self.vals exactly once.

    def __init__(self):
        """Create and empty set of integers"""
        self.vals == []

    def insert(self, e):
        """Assumes e is an integer and inserts e into self"""
        if not e in self.vals:
            self.vals.append(e)

    """I've omitted this part of the example code"""

    def __str__(self):
        """Returns a string representation of self"""
        self.vals.sort()
        result = ''
        for e in self.vals:
            result = result + str(e) + ','
        return '{' + result[:-1] + '}' # -1 omits trailing comma

The textbook says when type in:

print(type(IntSet), type(IntSet.insert))

will print:

<type 'type'> <type 'instancemethod'>

yet mine prints:

<class 'type'> <class 'function'>

After doing research I figured out that the type instancemethod is different from function for bounding reasons. Also, my Jupyter Notebook is running Python3, yet my textbook is an older edition which is written in Python2.


Solution

  • Both differences are mainly because the book you're following has been written to be followed with python2.x on your side. If you tested that book's code let's say with python2.7.x you'd get exactly the same book's output:

    (<type 'type'>, <type 'instancemethod'>)
    

    In fact, if your class wouldn't inherit from object and it was defined like class IntSet: you'd get the below output when using python2.7.x:

    (<type 'classobj'>, <type 'instancemethod'>)
    

    While if you're using python 3.6.x, no matter whether you inherit from object or not you'll just get:

    <class 'type'> <class 'function'>
    

    And that's basically because python3 uses new-style classes, so it doesn't matter whether your class inherits from object or not, it's still a new-style class. Also, inheriting from object is considered to be a good practice if you intend your code to be run with both python2 and python3.

    So yeah, nothing wrong on your side, just one of the differences between python2 and python3.

    NS: This https://wiki.python.org/moin/FromFunctionToMethod also may clarify a little bit further your question.