什么时候最好在Python中使用一个类?

时间:2012-05-16 21:49:23

标签: python oop class function

我是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)

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

您可以创建的类的主要值,并在对象上调用多个方法,例如打架还是睡觉?

4 个答案:

答案 0 :(得分:11)

你的例子相当简单。

在一个更完整的例子中,战斗不仅会显示当前状态 - 它还会修改该状态。你的怪物可能会受到伤害,这会改变它的生命值和士气。这个状态必须存储在某个地方。如果你使用一个类,添加实例变量来存储这个状态是很自然的。

仅使用功能,找到一个存放状态的好地方会更加困难。

答案 1 :(得分:2)

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

但是如果你需要编写一个必须同时跟踪两个独立怪物的程序,了解它们的健康状况,区分它们的战斗能力,那么,你可以看到封装每个怪物的价值。单独的怪物实例。

答案 2 :(得分:2)

我的怪物怎么样?他可以打另一个怪物!大概你的功能怪物不能那样做; - )

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

答案 3 :(得分:0)

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

  • 安全地跨特定功能共享状​​态

    类提供封装以避免污染全局命名空间 只需要在几个函数之间共享的变量。您不希望有人使用您的代码覆盖您的所有函数正在使用的变量 - 您总是希望能够尽可能地控制访问。

    可以实例化类,并且具有相同变量的多个独立副本,这些副本完全不共享,同时只需要很少的代码。

    当您需要将函数和变量的集合与另一个函数和变量集合之间的交互建模时,即当您需要对对象进行建模时,它们是合适的。为没有状态的单个函数定义一个类是坦率地浪费代码。

  • 提供运营商重载或定义特定类型的特定特征

    intstringtuples可以播放的内容(可用作词典中的键或插入set),list s和dict不是吗?

    答案:这些原始类型的基类实现了magic method __hash__,这使Python编译器能够在运行时动态计算哈希值。

    允许+运算符重载的内容是什么,5 + 2 = 7 int's' + 'a' = 'sa'__add__为字符串?

    答案:这些类型的基类定义了自己的{{1}}方法,可以让您准确定义如何在类的两个成员之间进行添加。

    所有用户定义的类都可以实现这些方法。它们有很好的用例:较大的数学库 - numpy,scipy和pandas - 通过定义这些魔术方法来大量使用运算符重载,为您提供处理数据的有用对象。类是在Python中实现这些特性和属性的唯一方法。

当不满足上述条件时,类不优于函数。

使用类以合理的方式将组合在一起有意义的函数和变量,或赋予对象特殊属性。其他任何事情都是多余的。