如何让Python类的属性依赖于外部变量?
如何让Python类的属性依赖于外部变量?
嘿,我完全get到你的需求了——就是想让类实例的属性能“绑定”到外部变量上,改外部变量的时候,所有相关的类实例属性自动跟着变,不用一个个去修改,对吧?
先说说你当前代码的问题哈:你在__init__里写了self.name = foo,这时候因为foo是字符串(不可变类型),其实是把当时foo的值(也就是"1")复制给了self.name。之后你把foo改成"2",这只是给foo重新赋值了一个新的字符串对象,和之前存在self.name里的"1"完全没关系了,所以打印出来还是"1"。
那怎么实现你要的效果呢?给你几个实用的方案:
方案1:用可变对象存外部值(比如列表)
因为像列表这种可变对象,赋值给实例属性的时候,存的是对象的引用,不是具体的值。之后修改可变对象里的内容,实例访问的时候就能拿到最新值。
foo = ["1"] # 用列表来存外部值,可变对象 class test(): def __init__(self, name_ref): self.name_ref = name_ref # 保存列表的引用 @property def name(self): return self.name_ref[0] # 每次访问name时,都取列表里的最新值 testVar = test(foo) foo[0] = "2" # 修改列表里的内容 print(testVar.name) # 输出:"2"
方案2:用@property直接读取全局外部变量
如果你的外部变量是全局的,可以直接在类里用@property装饰器,每次访问属性时都去读取最新的全局变量值:
foo = "1" class test(): @property def name(self): global foo # 声明使用全局的foo变量 return foo testVar = test() foo = "2" # 修改全局变量 print(testVar.name) # 输出:"2"
这个方法简单直接,但要注意全局变量的使用场景,要是有多个这样的实例,所有实例的name都会跟着foo的变化而同步更新,刚好符合你说的“改一个变量就能改所有同类型实例属性”的需求。
方案3:用专门的“值持有者”类封装外部值
这种方法更优雅,可读性也更好——用一个小类来持有可变的值,所有test实例都引用这个持有者对象:
# 专门用来存可变值的类 class ValueHolder: def __init__(self, value): self.value = value foo = ValueHolder("1") class test(): def __init__(self, holder): self.holder = holder # 保存持有者对象的引用 @property def name(self): return self.holder.value # 每次访问都取持有者的最新值 testVar = test(foo) foo.value = "2" # 修改持有者里的值 print(testVar.name) # 输出:"2"
核心思路其实就是:不可变类型(字符串、数字、布尔)赋值时是“传值”,而可变类型(列表、字典、自定义对象)是“传引用”。要让实例属性跟着外部变量变,要么用可变类型来存外部值,要么让属性每次访问时都去读取最新的外部变量。
备注:内容来源于stack exchange,提问作者Donkey45
相关产品推荐
相关产品推荐

