Python when to use classes

When is it best to use a class in Python?

I’m new to python and programming in general, so would really appreciate any clarification on this point. For example, in the following code:

 #Using a class class Monster(object): def __init__(self, level, damage, duration): print self self.level = level self.damage = damage self.duration = duration def fight(self): print self print "The monster's level is ", self.level print "The monster's damage is ", self.damage print "The attack duration is ", self.duration def sleep(self): print "The monster is tired and decides to rest." x = Monster(1, 2, 3) y = Monster(2, 3, 4) x.fight() y.fight() y.sleep() #just using a function def fight_func(level, damage, duration): print "The monster's level is ", level print "The monster's damage is ", damage print "The attack duration is ", duration fight_func(1, 2, 3) fight_func(5,3,4) 

The pure function version seems cleaner and gives the same result. Is the primary value of classes that you can create and call a number of methods on an object, e.g. fight or sleep?

4 Answers 4

Your example is rather simplified.

In a more complete example fighting wouldn’t just display the current state — it would also modify that state. Your monster might get hurt and that would change its hit points and morale. This state has to be stored somewhere. If you use a class it would be natural to add instance variables to store this state.

Using only functions it would be more difficult to find a good place to store the state.

Читайте также:  What is class phpmailer php

@Yoel: while I recommend perusal of SICP to anyone interesting in computing, I hardly see its value in this case. It teaches a functional programming style, not OOP.

Mark is suggesting that if the fight_func needs to track state about the fight, then creating a fight manager class that keeps the fight state internally would be a good idea. On the other hand, if the only state is the damage being done to the monsters, then you don’t really need it.

yes, but it does tackle the issue that @MarkByers and OP were getting at, about how state works in programming, functional and oop

@Yoel Python has some facilities intended for functional use, but calling it a functional language is something of a stretch.

Your example isn’t particularly interesting — it just prints three numbers. You don’t need classes, or even a function (really) to do that.

But if you ever need to write a program that has to keep track of two separate monsters at one time, know their health, differentiate their fighting abilities, and so, you can see the value of encapsulating each of the monsters in a separate monster instance.

I think I’ll have to come back later with a better example. Thank you for your explanation — it’s starting to make sense to me now. 🙂

what about my monsters? he can fight another monster! Presumably your functional monster cannot do that 😉

class Monster(object): def __init__(self, level, damage, duration): self.level = level self.damage = damage self.duration = duration def fight(self, enemy): if not isinstance(enemy, Monster) : print "The enemy is not a monster, so I can't fight it." return None else : print "Starting fighting" print "My monster's level is ", self.level print "My monster's damage is ", self.damage print "My monster's attack duration is ", self.duration print "The enemy's level is ", enemy.level print "The enemy's damage is ", enemy.damage print "The enemy's attack duration is ", enemy.duration result_of_fight = 3.*(self.level - enemy.level) + \ 2.*(self.damage - enemy.damage) + \ 1.*(self.duration - enemy.duration) if result_of_fight > 0 : print "My monster wins the brutal battle" elif result_of_fight < 0 : print "My monster is defeated by the enemy" else : print "The two monsters both retreat for a draw" return result_of_fight def sleep(self, days): print "The monster is tired and decides to rest for %3d days" % days self.level += 3.0 * days self.damage += 2.0 * days self.duration += 2.0 * days x = Monster(1, 2, 3) y = Monster(2, 3, 4) x.fight(y) x.sleep(10) 
Starting fighting My monster's level is 1 My monster's damage is 2 My monster's attack duration is 3 The enemy's level is 2 The enemy's damage is 3 The enemy's attack duration is 4 My monster is defeated by the enemy The monster is tired and decides to rest for 10 days 

Источник

Why should I use classes in python?

Why should I use class when I can write them simply like this:

def distanceFromPoint(p,q): # they are tuples y = (p[0]-q[0])**(2)+(p[1]-q[1])**(2) return y**(1/2) def reflectx(p): return (p[0],-p[1]) p = (3,3) q = (6,7) 

At least the getX and getY methods are not considered pythonic code. You can access the x and y attributes directly.

Apart from more general answers below: you don't really need the getX/getY. Python has no real private members, so using just x/y is ok. If you need to override them, properties are always available.

@Matthias: I am new to python. I can't understand what is pythonic code and why getX, getY are not pythonic codes ?

You don't need to lose sleep over what is or isn't 'Pythonic', but I hope you see that mypoint.x is simpler and clearer than mypoint.getX() . It's hard to illustrate the power of OOP in such a simple example though. I never really 'got it' until I had a real problem to solve, which I suddenly realised was amazingly straightforward if I wrote a class that inherited from someone else's previously defined class.

@nekomatic: Can you please mention one of those exercise in python OOP which led you to the "aha" moment ?

4 Answers 4

One of the big advantages of using OOP is extensibility.

Let's say you'd written an application that processes lots of data in the form of points. Now your customer adds to the specification that as well as the x and y coordinate of each point, your app needs to know what colour each point is.

If you'd written your code to store each point as a tuple, (x, y) , you might add the colour as a third value: (x, y, colour) . But now you have to go through all of your code to find the places where it's broken because you changed the data format. If you'd used a class, you could simply define a new class that inherits from Point and adds the necessary capabilities:

class ColouredPoint(Point): """ Class for points which are coloured, based on Point """ def __init__(self, initX, initY, initCol): Point.__init__(self, initX, initY) self.colour = initCol p = ColouredPoint(3, 3, "green") q = ColouredPoint(6, 7, "red") r = Point(8, 4) print(p.distanceFromPoint(q)) print(p.colour) print(p.distanceFromPoint(r)) 

All your code that worked with the Point class will still work with the new class, and you can do this even if you didn't write, or can't change, the definition of the Point class.

Источник

Оцените статью