When is it best to use a class in Python?

后端 未结 4 2003
小鲜肉
小鲜肉 2021-01-02 10:47

I\'m new to python and programming in general, so would really appreciate any clarification on this point.

For example, in the following code:

    #         


        
相关标签:
4条回答
  • 2021-01-02 11:12

    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.

    0 讨论(0)
  • 2021-01-02 11:16

    This is a more general answer than for just your code, but classes are useful when you need to:

    • Share state safely across specific functions.

      Classes offer encapsulation to avoid polluting the global namespace with variables that only need to be shared across a few functions. You don't want someone using your code to overwrite a variable all of your functions are using - you always want to be able to control access as much as possible.

      Classes can be instantiated and have multiple independent copies of the same variable that are not shared at all while requiring very little code use.

      They're appropriate when you need to model interactions between a collection of functions and variables with another collection of functions and variables i.e. when you need to model objects. Defining a class for a single function with no state is frankly a waste of code.

    • Provide operator overloading or define specific traits for certain types

      What makes int, string, and tuples hashable (can be used as keys in a dictionary or inserted into a set), while lists and dicts aren't?

      Answer: the base classes for these primitive types implement the magic method __hash__, which enables the Python compiler to dynamically compute a hash at runtime.

      What allows the + operator to be overloaded, so that 5 + 2 = 7 for ints but 's' + 'a' = 'sa' for strings?

      Answer: the base classes for these types defines their own __add__ method, which lets you define exactly how addition between two members of your class is carried out.

      All user-defined classes can implement these methods. There are good use cases for them: larger mathematical libraries - numpy, scipy, and pandas - make heavy use of operator overloading by defining these magic methods to provide you useful objects to handle your data. Classes are the only way to implement these traits and properties in Python.

    Classes are not superior to functions when the above conditions are not met.

    Use a class to group together meaningful functions and variables in a sensible way, or to endow your objects with special properties. Anything else is superfluous.

    0 讨论(0)
  • 2021-01-02 11:22

    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) 
    

    so:

    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
    
    0 讨论(0)
  • 2021-01-02 11:27

    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.

    0 讨论(0)
提交回复
热议问题