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

あなたの例は特に興味深いものではありません.3つの数字を出力するだけです. それを行うには、クラスも関数も (実際には) 必要ありません。

しかし、一度に 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

これは、コードだけよりも一般的な答えですが、クラスは次の必要がある場合に役立ちます。

  • 特定の関数間で状態を安全に共有します

    クラスは、いくつかの関数間で共有する必要がある変数でグローバル名前空間を汚染することを避けるために、カプセル化を提供します。コードを使用している誰かが、すべての関数が使用している変数を上書きすることは望ましくありません。アクセスを可能な限り制御できるようにする必要があります。

    クラスはインスタンス化でき、まったく共有されない同じ変数の複数の独立したコピーを持つことができますが、コードの使用はほとんど必要ありません。

    関数と変数のコレクションと別の関数と変数のコレクションとの相互作用をモデル化する必要がある場合、つまりオブジェクトをモデル化する必要がある場合に適しています。状態のない単一の関数のクラスを定義することは、率直に言ってコードの無駄です。

  • 演算子のオーバーロードを提供するか、特定の型に特定の特性を定義します

    intstring、および をハッシュ可能tuplesにする (辞書のキーとして使用したり、 に挿入したりできるset)のはなぜですか? lists とdicts はそうではありません。

    回答:これらのプリミティブ型の基本クラスは、マジック メソッド __hash__を実装します。これにより、Python コンパイラは実行時にハッシュを動的に計算できます。

    s ではなく文字列のように、+演算子をオーバーロードできるようにするものは何ですか?5 + 2 = 7int's' + 'a' = 'sa'

    回答: これらの型の基本クラスは独自の__add__メソッドを定義します。これにより、クラスの 2 つのメンバー間でどのように加算が実行されるかを正確に定義できます。

    すべてのユーザー定義クラスは、これらのメソッドを実装できます。それらには良いユースケースがあります: より大きな数学ライブラリ (numpy、scipy、pandas) は、データを処理するための便利なオブジェクトを提供するためにこれらの魔法のメソッドを定義することで、演算子のオーバーロードを多用します。クラスは、Python でこれらの特性とプロパティを実装する唯一の方法です。

上記の条件が満たされない場合、クラスは関数より優れていません。

クラスを使用して、意味のある関数と変数を適切な方法でグループ化したり、オブジェクトに特別なプロパティを付与したりします。それ以外は余計です。

于 2016-08-26T18:30:00.637 に答える