什么时候最好在Python中使用类?(When is it best to use a class

2019-06-24 12:54发布

我是新来的Python和编程一般,所以会很感激这一点任何澄清。

例如,在下面的代码:

    #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)

纯函数的版本似乎更清洁,并给出了相同的结果。

是的,你可以创建和调用上的对象,如打了许多的方法或类睡眠的首要价值?

Answer 1:

您的例子是相当简单。

在一个更完整的例子战斗不会只显示当前状态 - 它也将修改状态。 你的怪物可能会受到伤害,从而会改变它的生命值和士气。 这种状态必须被保存在某个地方。 如果你使用一个类很自然增添变量来保存这个状态。

只使用功能,这将是很难找到一个好地方来存储状态。



Answer 2:

你举的例子是不是特别有趣 - 它只是打印三个数字。 你不需要类,甚至是一个函数(真的)这样做。

但是,如果你需要写有跟踪的两个独立的怪物在同一时间的节目,知道自己的健康状况,区分他们的战斗能力,所以,你可以看到在一个单独的怪物例如封装每个怪物的价值。



Answer 3:

那我的怪物? 他可以打另一个怪物! 想必你的功能的怪物不能这样做;-)

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


Answer 4:

这比只是你的代码更一般的答案,但是当你需要类是有用的:

  • 共享状态下安全地跨越特定的功能

    类提供的封装,以避免污染全局命名空间变量只需要跨越几个功能共享。 你不希望别人使用你的代码覆盖所有的功能都使用一个变量 - 你总是希望能尽可能多地控制访问。

    类可以被实例化,并有不都同时需要很少的代码共享使用同一个变量的多个独立副本

    当你需要的函数和变量的集合之间的相互作用与功能的另一个集合模型,当你需要建模对象的变量,即他们是合适的。 定义一个类无状态的单一功能是坦然的代码的浪费。

  • 提供运算符重载或定义为某些类型的特殊性状

    是什么让intstringtuples哈希的(可以用作字典中的键或插入set ),而list S和dict s为呢?

    回答:这些原语类型的基类实现魔术方法 __hash__ ,这使得编译器的Python在运行时动态计算散列。

    什么允许+操作者被重载,以便5 + 2 = 7int秒,但's' + 'a' = 'sa'为字符串?

    答:对于这些类型的基类定义了自己的__add__方法,它可以让你定义究竟如何类的两个成员之间除了进行。

    所有用户定义的类可以实现这些方法。 有良好的用例为他们:较大的数学库 - numpy的,SciPy的,和熊猫 - 通过定义这些魔术方法,为您提供有用的对象来处理你的数据大量使用操作符重载。 类是实现这些特性和属性在Python的唯一途径。

当不满足上述条件的类不优于功能。

使用类组在一起有意义的函数和变量在一个合理的方式,或具有特殊性质赋予你的对象。 还有什么是多余的。



文章来源: When is it best to use a class in Python?