mooglinux
mooglinux

Reputation: 845

Extending a python list class to perform additional functions on its contents?

I want to create an object which will hold other objects, and call a method on each of the objects it holds. The end goal is to generate a script for a program. Each object contains a command that can be printed with printCommand(), eventually into a file. My original solution was this:

a = ObjectList()
a.appendObject(Object())
b = ObjectList()
b.appendObject(Object())

listOfObjects = [a, b]
for Object in listOfObjects:
    Object.printCommand()

I create a list variable, add objects to thw list, then loop over it issuing the command. While this works, I am primarily doing this excersize to teach myself programming, so I want to know if there is a more elegant solution than writing code to append, pop, etc. items to a list in an object. Since list already contains these functions, i was thinking the correct thing to do would be to extend list:

class Object:
    def __init__(self):
        self.Command = "Script Command"

    def printCommand(self):
        print(self.Command)

class ObjectList(list):
    def printCommand(self):
        for Object in self.LISTCONTENTS:
            Object.printCommand()

However, I am at a loss as to how I would tell it to iterate over its own contents. What belongs at self.LISTCONTENTS? Where does a list object store its contents, and how do you access them from a method?

Upvotes: 2

Views: 1835

Answers (2)

Rob Wouters
Rob Wouters

Reputation: 16327

You can just iterate over self:

The superclass methods (i.e., __iter__()) are all present. Saying self in the context of a for statement will cause the appropriate methods to be invoked.

class Object:
    def __init__(self):
        self.Command = "Script Command"

    def printCommand(self):
        print(self.Command)

class ObjectList(list):
    def printCommand(self):
        for Object in self:
            Object.printCommand()

lst = ObjectList()
lst.append(Object())
lst.append(Object())

lst.printCommand()

The way this works is list implements __iter__ which is called behind the scenes when iterating over an object:

>>> for e in [1,2,3].__iter__():
...  print(e)
... 
1
2
3
>>> for e in [1,2,3]:
...  print(e)
... 
1
2
3

Upvotes: 1

Marcin
Marcin

Reputation: 49816

(a) Don't ever create a class called Object, that's far too close to object.

(b) There is absolutely no need to inherit from list, and frankly I doubt the need to use your own class at all.

(c) The normal way to invoke a function on every element of a list is to use map. If you need to map with the same function repeatedly, you can use partial to bind that function to map's first argument.

Now go look at the documentation.

Upvotes: 1

Related Questions