Python实现通用getter访问类私有属性 避免重复编写@property
解决方案
你想要的通用getter完全可以实现,核心是利用Python对双下划线私有属性的**名称改写(name mangling)**规则:类中定义的__attr会被自动改写为_类名__attr的格式存储,只要动态拼接这个属性名就能用内置的getattr()方法取值。
方案1:实现显式的通用get_attr方法
直接在类中添加如下方法,完全匹配你预想的调用逻辑:
class Character: # 私有字段保留原有定义 __age = 18 __weight = 200 __height = 72 def __init__(self, name): self.__name = name # 通用getter方法 def get_attr(self, attr): # 拼接改写后的私有属性名 private_attr = f"_{self.__class__.__name__}__{attr}" if hasattr(self, private_attr): return getattr(self, private_attr) raise AttributeError(f"没有名为 {attr} 的私有属性") # 调用示例 person = Character("someone") print("name =", person.get_attr("name"), ",", "age =", person.get_attr("age"))
运行后输出和你原来的代码完全一致,不需要再给每个私有属性单独写@property。
方案2:用__getattr__魔法方法实现属性式访问
如果连get_attr方法名都不想写,希望直接用person.name、person.age的形式取值,可以用Python的__getattr__钩子方法,访问不存在的属性时会自动触发该方法:
class Character: __age = 18 __weight = 200 __height = 72 def __init__(self, name): self.__name = name def __getattr__(self, attr): private_attr = f"_{self.__class__.__name__}__{attr}" if hasattr(self, private_attr): return getattr(self, private_attr) raise AttributeError(f"没有名为 {attr} 的属性") # 调用示例 person = Character("someone") print("name =", person.name, ",", "age =", person.age)
这种方案的调用体验和你写多个@property完全一致,代码量大幅减少。
注意事项
- 如果你没有强制要求用双下划线私有属性,也可以用单下划线开头的约定式私有属性(比如
_age、_name),不需要处理名称改写逻辑,通用方法的拼接规则可以简化为直接取f"_{attr}"即可。 - 两种方案都只做了只读处理,如果需要通用setter,可以用类似逻辑实现
set_attr方法或者__setattr__钩子。
内容的提问来源于stack exchange,提问作者Luke Autry
相关产品推荐
相关产品推荐

