Python:在字典中链接/绑定变量

2 投票
8 回答
13878 浏览
提问于 2025-04-15 12:32

这是我第一次发帖,希望大家友好对待!

我有一个关于Python字典的基本问题。我想要一个字典的值能够在另一个变量改变时自动更新(或者至少在下次调用时重新计算)——比如:

mass = 1.0
volume = 0.5
mydict = {'mass':mass,'volume':volume}
mydict['density'] = mydict['mass']/mydict['volume']

在这个例子中,mydict['density'] 只是返回 2.0。如果我把 mydict['mass'] 改成 2.0,密度就不会更新。这没问题,我大致能理解原因——密度是根据最初传入的值来定义的。所以我想也许可以用一个lambda表达式来解决这个问题,比如(抱歉代码写得很糟糕!):

mydict['density_calc'] = lambda x,y: x/y
mydict['density'] = mydict['density_calc'](mydict['mass'],mydict['volume'])

但再次强调,这仍然只返回原来的密度,尽管我已经改变了 mydict['mass']。作为最后的尝试,我试了这个:

def density(mass,volume): return mass/volume
mydict['density_calc'] = lambda x,y: density(x,y)
mydict['density'] = mydict['density_calc'](mydict['mass'],mydict['volume'])

结果还是不行。这看起来是个很简单的问题,所以提前道歉,如果有人能帮我解决这个,我会非常感激!

谢谢,

Dave

8 个回答

6

在这种情况下,最好是创建一个类来处理这个问题,并使用动态属性。例如:


class Body(object):
    def __init__(self):
        self.mass=1.0
        self.volume=0.5

    @property
    def density(self):
        return self.mass/self.volume

这样你就可以得到质量、体积和密度这几个属性,其中密度是根据其他两个值计算出来的。例如:


b=Body()
b.mass=1
b.volume=0.5
print b.density # should be 2

b.mass=2.0
print b.density # should be 4

不过,如果你坚持使用字典的话,可能需要对它进行扩展,并重写一些“魔法”方法,比如 __getitem____setitem__,这样可以在质量发生变化时或者在访问密度时进行检测,并根据需要重新计算。

9

这看起来像是对字典结构的滥用。为什么不直接创建一个简单的类呢?

class Entity(object):
    def __init__(self, mass, volume):
        self.mass = mass
        self.volume = volume
    def _density(self):
        return self.mass / self.volume
    density = property(_density)
-2

这里有一个简单的方法,教你如何创建一个自己的字典类(dict的子类),虽然这个类可能不完全符合Python字典的标准:

class MyDict(dict):
    def __getitem__(self, key):
        if key == 'density':
           return self['mass'] / self['volume']
        else:
            return dict.__getitem__(self,key)
    def keys(self):
        return ['density'] + dict.keys(self)

x = MyDict()
x['mass'] = 1.0
x['volume'] = 0.5

print x

print x.keys()

print x['density']

x['mass'] = 2.0

print x['density']

这个代码会输出

{'volume': 0.5, 'mass': 1.0}
['density', 'volume', 'mass']
2.0
4.0

不过,这个方法没有考虑到字典中的一些功能,比如dict.iterkeys()等其他功能。

撰写回答