3

関数/式Fの結果である変数Aを持っているとしましょう.Fには、X、Y、Zとしましょう.

X、Y、または Z が変更されるたびに A が自動的に更新されるように、A を F にバインドすることは可能ですか?

私が避けたいのは、X、Y、Z が変更されるたびに、コード内で明示的に A を更新することを覚えておく必要があるということです。また、A を使用するたびに関数を呼び出したくありません。

例(要求どおり):次の関数があります:

def calcHits():
    return sum(hitDiceRolls,level*modList['con']) 

私のプログラム (関数の外側) には、hitPoints という変数があります (はい、これはロールプレイング ゲーム プログラムです)。関数で使用される変数が変更されるたびに、hitPoints も変更する必要があります。

4

2 に答える 2

4

Pythonでこれを行う一般的な方法は、class:を使用することです。

class ExpressionBinder:
    def __init__(self, f):
        self.f = f
        self.x = 0
        self.y = 0
        self.z = 0

    @property
    def result(self):
        return self.f(self.x, self.y, self.z)

次のように使用できます。

def f(x, y, z):
    return x**3 + y**2 + z

b = ExpressionBinder(f)
b.x = 1
b.y = 2
b.z = 3
print(b.result)
于 2012-04-22T07:30:59.593 に答える
2

他の名前が再バインドされた場合に、グローバルまたはローカル スコープで名前を自動的に再バインドする方法は Python にはありません。ただし、いくつかの値を追跡できるクラスを作成し、呼び出した値を返すメンバー関数を持つことができるはずですA。また、@Alok が指摘したように、プロパティ記述子を使用して、関数を暗黙的に呼び出してその値を返すメンバー名を作成できるため、関数を非表示にして名前をプレーンな古い名前のように扱うことができます。

class Trk(object):
    """Track some values and compute a function if any change"""
    def __init__(self, name, fn, **objects_to_track):
        def _trk_fn(self):
            if any(self.__dict__[x] != self.original_objects[x] for x in self.original_objects):
                self.value = self.saved_fn(self.__dict___)
                # now that self.value is updated, also update self.original_objects
                for x in self.original_objects:
                    self.original_objects[x] = self.__dict__[x]
            return self.value

        self.original_objects = objects_to_track  # make reference copy
        self.__dict__.update(objects_to_track)
        self.name = name
        self.saved_fn = fn
        self.fn = self._trk_fn()
        self.value = self.fn()

申し訳ありませんが、私は今とても疲れていて、この例を終えることができません. 私もそれをテストしませんでした。しかし、これは値を追跡する 1 つの方法を示しており、値が異なる場合は別のことを行います。次のように使用します。

# want to track x, y, z
trk = Trk(x, y, z)
trk.fn() # returns up-to-date value

trk.x = new_value
trk.fn() #detects that trk.x changed and computes new trk.value

上記が機能する場合は、プロパティ記述子を使用して名前をバインドし、名前から値を読み取ろうとすると呼び出されるようにすることができますself.fn()

編集:ああ、更新されたときself.valueに更新するself.original_objects必要があることが重要です。そのためのコードを追加しました。

そして今から寝ます!

于 2012-04-22T08:08:18.153 に答える