-1

I am new to Python and I am trying to find a way to add new methods to pre-existing classes in Python. For example, to add a .print() method to the list class.

I know I can create a new class that inherits the list class and add this method like so:

    import builtins
    class list(list):
            def print(self):
                    builtins.print(self)

But this doesn't modify the pre-existing 'list' class. I can do assignments like this: trial_list = list([3,4,6]) but not like this: trial_list = [3,4,6].

Also, is there a way to view the actual content of the list class besides dir() and help()?

sophros
  • 14,672
  • 11
  • 46
  • 75
Anmol Saksena
  • 91
  • 2
  • 10
  • 2
    You cannot do this with the built-in types, because they are implemented in a special way (they way they work is so fundamental that it doesn't make sense to express in native Python code). For other classes, you can modify them without inheriting, but it is usually a bad idea. If you want to look this up, it is called "monkey-patching" and is easy to search for on the web. – Karl Knechtel Nov 13 '20 at 05:13
  • 1
    https://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object-instance – Frank Yellin Nov 13 '20 at 05:14
  • Thanks, also is there a way to view the methods inside a predefined class the way they are defined. For example, is there a way to view the __init__ method of the list class? – Anmol Saksena Nov 13 '20 at 05:17
  • Frank Yellin, I looked at the link you provided and I tried to add the .print() method to an instance of the list class but it still does not work. – Anmol Saksena Nov 13 '20 at 05:42

1 Answers1

1

The recommended approach to subclass built in container types, is to use the abstract base classes provided in the collections module:

In the case of list, you should use collections.UserList

from collections import UserList

class MySpecialList(UserList):
    def print(self):
        print(self)
        
seq = MySpecialList([1, 2, 3])
print(seq)
seq.print()

You can now create MySpecialList objects the way you do with a plain python list.

Subclassing requirements: Subclasses of UserList are expected to offer a constructor which can be called with either no arguments or one argument. List operations which return a new sequence attempt to create an instance of the actual implementation class. To do so, it assumes that the constructor can be called with a single parameter, which is a sequence object used as a data source.

Of course you can override the methods of list to provide your MySpecialList with the behavior you need.

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • So i added the import statement and inherited UserList but the assignment try_list = [4,6,8] still does not allow me to use try_list.print(). – Anmol Saksena Nov 13 '20 at 05:41
  • You cannot use the square brackets shortcut to create a subclass of `UserList`; these are reserved to python `list`. You can create a `UserList` by providing the required arguments to the constructor, as quoted in my answer. I added a method `print` to `MySpecialList`; you can call it using dot notation. – Reblochon Masque Nov 13 '20 at 05:47
  • but I did that by inheriting the list class directly. Why do I need to inherit collections.UserList? – Anmol Saksena Nov 13 '20 at 05:53
  • Let the master explain this to you: [Raymond Hettinger «Build powerful, new data structures with Python's abstract base classes»](https://www.youtube.com/watch?v=S_ipdVNSFlo) – Reblochon Masque Nov 13 '20 at 06:00