Shyam Sunder
Shyam Sunder

Reputation: 1240

Creating multiple objects within the same class in Python

I want to be able to return multiple objects of a class by using a method within the class. Something like this.

class A:
    def __init__(self,a):
    self.a = a

    def _multiple(self,*l):
        obj = []
        for i in l:
            o = self.__init__(self,i)
            obj.append(o)
        return obj

When I execute this on iPython (iPython 0.10 and Python 2.6.6) I get the following

In [466]: l = [1,2]
In [502]: A._multiple(*l)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

TypeError: unbound method _multiple() must be called with A instance as 
first argument (got int instance instead)

I'm definitely unclear about the invocation as well as the 'self' keyword usage. Could you help me out in getting this correct?

Thank you.

Upvotes: 3

Views: 9154

Answers (3)

Abhijit
Abhijit

Reputation: 63737

TypeError: unbound method _multiple() must be called with A instance as first argument (got int instance instead)

The Error is self explanatory. It means that an instance method is being called as a Class method. To make the instance method as a class method add the decorator @classmethod

>>> class A:
    def __init__(self,a):
        self.a = a
    @classmethod
    def _multiple(cls,*l):
        #Create multiple instances of object `A`
        return [A(i) for i in l]

>>> l = [1,2]
>>> A._multiple(*l)
[<__main__.A instance at 0x066FBB20>, <__main__.A instance at 0x03D94580>]
>>> 

Upvotes: 3

Duncan
Duncan

Reputation: 95652

You want a class method:

class A:
    def __init__(self,a):
        self.a = a

    @classmethod
    def _multiple(cls,*l):
        obj = []
        for i in l:
            o = cls(i)
            obj.append(o)
        return obj


>>> A._multiple(1, 2) # returns 2 A's
[<__main__.A instance at 0x02B7EFA8>, <__main__.A instance at 0x02B7EFD0>]

The classmethod decorator replaces the usual self as the first parameter with a reference to the class (in this case A). Note that doing it this way means if you subclass A and call _multiple on the subclass it will be passed the subclass instead.

class B(A): pass

>>> B._multiple(1, 2, 3)
[<__main__.B instance at 0x02B87C10>, <__main__.B instance at 0x02B87D28>, <__main__.B instance at 0x02B87CD8>]

would create a list of B objects.

Upvotes: 1

Michael Aaron Safyan
Michael Aaron Safyan

Reputation: 95499

Simply replace:

 self.__init__(self, i)

With:

 A(i)

The reason for this is that the init method mutates the object on which it is called, and "self" is the current instance. You use the constructor (the same name as the class) to create a new instance.

Upvotes: 0

Related Questions