optional argument to a subclass of a class

Alex Hall mehgcap at gmail.com
Fri May 21 08:13:53 EDT 2010


On 5/21/10, Peter Otten <__peter__ at web.de> wrote:
> Alex Hall wrote:
>
>> Hi all,
>> I am now trying to allow my classes, all of which subclass a single
>> class (if that is the term), to provide optional arguments. Here is
>> some of my code:
>>
>> class Craft():
>>  def __init__(self,
>>  name,
>>  isAircraft=False,
>>  id=helpers.id(),
>>  hits=0,
>>  weapons=[]):
>>   self.name=name
>>   self.id=id
>>   self.hits=hits
>>   self.weapons=weapons
>>   self.isAircraft=isAircraft
>>  #end def
>> #end class
>>
>>
>> #now a class for each type of craft in the game
>> #each will subclass the Craft class, but each also has its own settings
>>
>> class Battleship(Craft):
>>  def __init__(self,
>>  name,
>>  maxHits):
>>   Craft.__init__(self, name)
>>   self.maxHits=maxHits
>>   self.length=maxHits #in Battleship, each ship's length is the same
>> as how many times it can be hit
>>  #end def
>> #end class
>>
>>
>> I want to be able to say something like
>> b=Battleship("battleship1", 4, weapons=["missile1","missile2"])
>> When I do that, though, I get a traceback on the above line saying
>> "type error: __init__() got an unexpected keyword argument 'weapons'".
>> What did I do wrong / what do I need to change so that any Craft
>> (Battleship, Carrier, and so on) can optionally provide a list of
>> weapons, or any other arguments to which I assign default values in my
>> Craft class? I hope this makes sense.
>
> You have to repeat the arguments for the base class in the Battleship
> initializer. Battleship(...) will only invoke Battleship.__init__(...), not
> Craft.__init__(...) -- so you have to do that explicitly inside
> Battleship.__init__() while passing along all parameters it is supposed to
> process. As simplified example:
>
> class Craft(object):
>     def __init__(self, name, id=None, weapons=None):
>         if id is None:
>             id = helpers.id()
>         if weapons is None:
>             weapons = []
>         self.name = name
>         self.id = id
>         self.weapons = weapons
>
> class Battleship(Craft):
>     def __init__(self, name, id=None, weapons=None, max_hits=None):
>         Craft.__init__(self, name, id, weapons)
>         self.max_hits = max_hits
>
> Notice how using None to signal that a value was not provided simplifies
> things; without it you'd have to put a meanigful default for weapons into
> both the Craft and Battleship class. If you want a unique id for every Craft
> providing helpers.id() as a default is just wrong; default arguments are
> calculated once and you would end up with the same id for every Craft
> instance.
Yes, I found that out the hard way :), but it made perfect sense as
soon as I realized that I was not getting unique IDs; the class()
statement is just a fancy function call in Python, as I understand it,
so of course it would be called only once, not each time I make a new
instance.
>
> Peter
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehgcap at gmail.com; http://www.facebook.com/mehgcap



More information about the Python-list mailing list