-1

So i have a class:

class Unit(object):
    def __init__(self, name, x , y, z):
        self.name = name
        self.strength = x + y
        self.intelligence = x + z 
        self.speed = y + z - x

and two species of these Units

class Red(Unit):
    def __init__(self, name, x, y, z):
        Unit.__init__(self,name, x, y, z)
        self.strength = self.strength * 2   

class Blue(Unit):
    def__init__(self, name, x, y, z):
        Unit.__init__(self, name, x, y, z)
        self.speed = self.speed * 2

I want the race to be decided based on what x, y, z, was used as input (z > x means the unit belongs to class Red and x > z means the unit belongs to class Blue) without having to set one before hand, how do I do this?

  • So you want e.g. `isinstance(Unit(1, 2, 3), Red)` to be `True`? – jonrsharpe Oct 09 '15 at 14:23
  • I basically want something that if i plugged in say ben = Class('Ben', 1, 4, 5) it would decide whether ben was part of the Red or Blue class – Danny Quinn Oct 09 '15 at 14:28
  • 2
    Then yes, you probably want the [*"factory method pattern"*](https://en.wikipedia.org/wiki/Factory_method_pattern) as @xi_ shows. Possible duplicate of http://stackoverflow.com/q/7273568/3001761 – jonrsharpe Oct 09 '15 at 14:29
  • Thanks so much, yes was worried this wasn't a good question but wasn't sure what to search for! – Danny Quinn Oct 09 '15 at 14:36

2 Answers2

2

You could create function for that:

def builder(name, x, y, z):
    if z > x:
        return Red(name, x, y, z)
    elif x > z:
        return Blue(name, x, y, z)
xiº
  • 4,605
  • 3
  • 28
  • 39
  • Thanks that looks like what I'm looking for, I've basically been using random numbers to generate a players stats and I want these random stats to be used to decide what class to use – Danny Quinn Oct 09 '15 at 14:26
0

You can set the __class__ attribute in your __init__:

class Unit(object):
    def __init__(self, name, x , y, z):
        self.name = name
        self.strength = x + y
        self.intelligence = x + z 
        self.speed = y + z - x

        if z > x:
            self.__class__ = Red
        else:
            self.__class__ = Blue

red = Unit("foo", 1,2,3)
blue = Unit("bar", 3,2,1)

You can also create a factory method that instantiates the appropriate class. You can do this as a stand-alone function, or you could make a class method. Here's the stand-alone version:

def unit_factory(name, x, y, z):
    if x > z:
        return Red(name, x, y, z)
    return Blue(name, x, y, z)

red = unit_factory("foo", 1, 2, 3)
blue = unit_factory("bar", 3, 2, 1)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685