2

I've got a piece of code which contains a for loop to draw things from an XML file;

   for evoNode in node.getElementsByTagName('evolution'):
      evoName    = getText(evoNode.getElementsByTagName(        "type")[0].childNodes)
      evoId      = getText(evoNode.getElementsByTagName(      "typeid")[0].childNodes)
      evoLevel   = getText(evoNode.getElementsByTagName(       "level")[0].childNodes)
      evoCost    = getText(evoNode.getElementsByTagName("costperlevel")[0].childNodes)

      evolutions.append("%s x %s" % (evoLevel, evoName))

Currently it outputs into a list called evolutions as it says in the last line of that code, for this and several other for functions with very similar functionality I need it to output into a class instead.

class evolutions:
    def __init__(self, evoName, evoId, evoLevel, evoCost)
        self.evoName = evoName
        self.evoId = evoId
        self.evoLevel = evoLevel
        self.evoCost = evoCost

How to create a series of instances of this class, each of which is a response from that for function? Or what is a core practical solution? This one doesn't really need the class but one of the others really does.

3
  • a note about style, you should always name classes with camel case starting with a capital letter, and they shouldn't be plural. It should be: class Evolution Commented Jan 13, 2009 at 20:39
  • You can also remove the 'evo' prefix from the class fields, they can be inferred from the context of the class. Saves typing. :) Commented Jan 13, 2009 at 20:50
  • Don't Repeat Yourself (DRY): get = lambda name: getText(evoNode.getElementsByTagName(name)[0].childNodes) Commented Aug 30, 2009 at 12:10

2 Answers 2

4

A list comprehension might be a little cleaner. I'd also move the parsing logic to the constructor to clean up the implemenation:

class Evolution:
    def __init__(self, node):
        self.node = node
        self.type = property("type")
        self.typeid = property("typeid")
        self.level = property("level")
        self.costperlevel = property("costperlevel")
    def property(self, prop):
        return getText(self.node.getElementsByTagName(prop)[0].childNodes)

evolutionList = [Evolution(evoNode) for evoNode in node.getElementsByTagName('evolution')]

Alternatively, you could use map:

evolutionList = map(Evolution, node.getElementsByTagName('evolution'))
Sign up to request clarification or add additional context in comments.

1 Comment

property is a built-in function in Python. It is a bad style to use it the way you did. docs.python.org/library/functions.html#property
3
for evoNode in node.getElementsByTagName('evolution'):
  evoName      = getText(evoNode.getElementsByTagName("type")[0].childNodes)
  evoId      = getText(evoNode.getElementsByTagName("typeid")[0].childNodes)
  evoLevel   = getText(evoNode.getElementsByTagName("level")[0].childNodes)
  evoCost      = getText(evoNode.getElementsByTagName("costperlevel")[0].childNodes)

  temporaryEvo = Evolutions(evoName, evoId, evoLevel, evoCost)
  evolutionList.append(temporaryEvo)

  # Or you can go with the 1 liner
  evolutionList.append(Evolutions(evoName, evoId, evoLevel, evoCost))

I renamed your list because it shared the same name as your class and was confusing.

2 Comments

Could you also rename their class to be Uppercase, like Proper Class Names Should Be?
I thought that was just me that put classes as Uppercase for the first letter. Or do you mean all letters?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.