On 5/21/10, Peter Otten <__pete...@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) mehg...@gmail.com; http://www.facebook.com/mehgcap -- http://mail.python.org/mailman/listinfo/python-list