Python类中字典内F-string未随实例属性更新的问题咨询
问题分析与解决
问题描述
实例化Test类并调用main()方法时,程序输出https://bunch/of/urls/with/None/,但预期输出https://bunch/of/urls/with/1234/。明明在main里先调用b_func(1234)更新了self.id,再调用a_func()取字典值,可字典里的F-string没跟着更新。
代码如下:
class Test(): def __init__(self,id=None): self.id = id # Problem happens here self.a_dict = {'a' : f'https://bunch/of/urls/with/{self.id}/'} def a_func(self): val = self.a_dict['a'] print(val) # It prints # https://bunch/of/urls/with/None/ # Not # https://bunch/of/urls/with/1234/ def b_func(self, id): self.id = id return True def main(self): self.b_func(1234) self.a_func() if __name__ == '__main__': a = Test() a.main()
背后的核心概念
F-string(格式化字符串字面量)是在定义时就完成求值的,并非动态实时计算。在__init__方法里创建self.a_dict时,f'https://bunch/of/urls/with/{self.id}/'会直接把当时的self.id值(也就是None)代入,生成固定的字符串存在字典里。后续修改self.id,已经生成的字符串不会自动重新计算。
修复方案
这里提供几种可行的修复方式:
方案1:更新self.id时同步更新字典值
修改b_func方法,每次更新self.id后,重新生成字典里的字符串:
def b_func(self, id): self.id = id self.a_dict['a'] = f'https://bunch/of/urls/with/{self.id}/' return True
方案2:把字典值改成动态计算的属性
利用Python的property装饰器,让a_dict每次被访问时都重新生成,确保拿到最新的self.id:
class Test(): def __init__(self,id=None): self.id = id @property def a_dict(self): return {'a' : f'https://bunch/of/urls/with/{self.id}/'} def a_func(self): val = self.a_dict['a'] print(val) def b_func(self, id): self.id = id return True def main(self): self.b_func(1234) self.a_func()
方案3:用方法代替字典直接生成URL
如果不需要完整的字典,也可以直接写一个生成URL的方法,每次调用时计算最新值:
class Test(): def __init__(self,id=None): self.id = id def get_a_url(self): return f'https://bunch/of/urls/with/{self.id}/' def a_func(self): val = self.get_a_url() print(val) def b_func(self, id): self.id = id return True def main(self): self.b_func(1234) self.a_func()
内容的提问来源于stack exchange,提问作者Chirath LV
相关产品推荐
相关产品推荐

