在Python中,我可以将变量绑定到函数/表达式以便它自动更新吗?

在Python中,我可以将变量绑定到函数/表达式以便它自动更新吗?,python,Python,假设我有一个变量a,它是一个函数/表达式F的结果,而F又有很多其他变量,比如X,Y和Z 是否可以将A绑定到F,以便在X、Y或Z发生变化时,A将自动更新 我想避免的是,每次X、Y和Z发生变化时,我都必须记住在代码中显式地更新A。我也不想每次使用A时都调用这个函数 示例(根据请求):我有以下函数: def calcHits(): return sum(hitDiceRolls,level*modList['con']) 在我的程序中(函数之外),我有一个变量叫做hitPoints(是的,

假设我有一个变量a,它是一个函数/表达式F的结果,而F又有很多其他变量,比如X,Y和Z

是否可以将A绑定到F,以便在X、Y或Z发生变化时,A将自动更新

我想避免的是,每次X、Y和Z发生变化时,我都必须记住在代码中显式地更新A。我也不想每次使用A时都调用这个函数

示例(根据请求):我有以下函数:

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

在我的程序中(函数之外),我有一个变量叫做hitPoints(是的,这是一个角色扮演游戏程序)。每当函数中使用的变量发生变化时,我希望命中点也发生变化。

在Python中实现这一点的典型方法是使用

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

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()
很抱歉,我现在很累,我不能完成这个例子。我也没有测试它。但这显示了一种跟踪值的方法,如果它们不同,就做些不同的事情。您可以这样使用它:

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)
# 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\u对象,这一点很重要。我添加了代码来实现这一点


现在我要睡觉了

你需要举一个例子,你能用这样的东西吗?我一直在看,它会起作用的。在这种情况下,我将编写代码来更新类的setter部分中的相关变量。谢谢。我也喜欢发送实际函数的优雅(这使得它非常动态)。每次我不想使用结果值时,它仍然会拉取结果,但我猜这是当前唯一的解决方案。如果函数运行成本很高,您可以缓存结果,并且只有在输入值自上次运行以来发生更改时才重新计算结果。是的,我必须检查一下。谢谢哇,我不知道
@property
!那很有用。