8

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

4 回答 4

11

您的示例相当简化。

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

仅使用函数会更难找到存储状态的好地方。

于 2012-05-16T21:52:52.130 回答
2

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

但是,如果您需要编写一个程序来同时跟踪两个不同的怪物、了解它们的健康状况、区分它们的战斗能力等等,那么您可以看到将每个怪物封装在一个单独的怪物实例中的价值.

于 2012-05-16T21:55:03.020 回答
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
于 2012-05-16T22:37:15.127 回答
0

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

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

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

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

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

  • 提供运算符重载或为某些类型定义特定特征

    是什么使int,stringtupleshashable (可以用作字典中的键或插入到 a 中set),而lists 和dicts 不是?

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

    是什么允许+运算符重载,以便5 + 2 = 7ints 而不是's' + 'a' = 'sa'字符串?

    回答:这些类型的基类定义了它们自己的__add__方法,这使您可以准确地定义如何在类的两个成员之间进行加法。

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

不满足上述条件时,类不优于功能。

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

于 2016-08-26T18:30:00.637 回答