Reputation: 1240
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
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
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
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