使用@property与@setter获取类私有属性是否合理?还有哪些方法?
使用@property操作私有属性的合理性及其他属性访问方法
一、你的@property实现完全合理
你用@property和@name.setter操作私有属性__name的写法是非常规范的Python封装实现,合理性体现在这几点:
- 数据合法性校验:setter里判断输入是否为非空字符串,能避免非法值被赋值给私有属性,这是直接暴露属性做不到的。
- 封装性与接口统一:外部代码用
os.name这种直观的属性语法访问,不用调用get_name()/set_name()这类方法,既保留了私有属性的封装性,又让调用体验更自然。 - 可扩展性强:以后如果要给属性访问加日志、缓存,或者修改校验逻辑,只需要修改getter/setter的实现,外部调用代码完全不用改。
你的代码运行后,设置os.name = 'Elizabeth'会触发setter的校验(符合条件就修改__name),获取os.name会触发getter的日志打印,完全符合预期。
二、访问私有/保护属性的其他方法
Python里的私有属性(__开头)和保护属性(_开头)有不同的访问方式,除了@property,还有这些方法:
1. 直接访问保护属性(_开头)
保护属性是Python社区的约定俗成,没有强制的访问限制,外部可以直接通过对象._属性名访问或修改:
# 示例(假设类中定义的是保护属性_surname) os = Person('Alexandra', 'Houston') print(os._surname) os._surname = 'Clark'
2. 访问名称修饰后的私有属性
Python会对__开头的私有属性做名称修饰,把__name变成_Person__name(格式为_类名__属性名),所以可以直接通过这个修饰后的名称访问:
os = Person('Alexandra', 'Houston') print(os._Person__name) # 直接获取私有属性 os._Person__name = 'Anna' # 直接修改私有属性 os.show() # 会打印Miss: Anna Houston
但这种方法非常不推荐,因为破坏了类的封装性,一旦类名修改,这个写法就会失效,而且绕过了类的校验逻辑。
3. 普通的get/set方法
不用@property,直接定义普通方法来获取和修改属性:
class Person: def __init__(self, name, surname): self.__name = name self.__surname = surname def get_name(self): print("Retrieving private attribute") return self.__name def set_name(self, m): if isinstance(m, str) and len(m) > 0: self.__name = m else: print("Error: Must be a non-empty string!") os = Person('Alexandra', 'Houston') os.set_name('Elizabeth') print(os.get_name())
这种方法也能实现封装,但调用时需要用函数调用的语法,不如@property的属性式写法简洁。
4. 使用vars()函数
vars()函数可以获取对象的属性字典,通过字典键访问修饰后的私有属性:
os = Person('Alexandra', 'Houston') print(vars(os)['_Person__name']) # 获取私有属性 vars(os)['_Person__name'] = 'Carol' # 修改私有属性
本质和直接访问修饰后的属性一样,同样不推荐使用。
内容的提问来源于stack exchange,提问作者aleksandrapacia
相关产品推荐
相关产品推荐

