如何在Python类的__init__构造方法中实现只读属性
如何在Python中实现类属性的只读(非方法)?
你希望类实例的full_name属性在初始化后无法被修改,但当前代码里用户可以直接赋值更改。下面是两种简单易懂的实现方式:
方法一:使用@property装饰器(最常用简洁)
这是Python实现只读属性的标准方式,通过装饰器把方法伪装成属性,只提供读取逻辑,不暴露修改入口。
修改后的代码:
class Test: def __init__(self, fname: str, lname: str): self.first_name = fname self.last_name = lname @property def full_name(self): # 直接调用私有方法生成全名 return self.__private_fullname(self.first_name, self.last_name) def __private_fullname(self, name1, name2): return name1 + ' ' + name2 # 测试 name = Test('John','Watson') print(name.full_name) # 输出 'John Watson' name.full_name = 'someone else' # 触发错误:AttributeError: can't set attribute
说明:
@property把full_name变成了只读属性,外部访问时就像访问普通实例变量一样,但无法直接赋值。- 如果用户尝试修改,Python会直接抛出
AttributeError,阻止非法修改。 - 这种方式代码清晰,符合Python的惯用写法,维护成本低。
方法二:重写__setattr__方法(适合批量控制只读属性)
如果需要同时控制多个只读属性,可以通过拦截属性赋值操作实现:
class Test: def __init__(self, fname: str, lname: str): self.first_name = fname self.last_name = lname # 初始化时用父类的__setattr__完成赋值,绕开自己的拦截逻辑 super().__setattr__('full_name', self.__private_fullname(fname, lname)) def __private_fullname(self, name1, name2): return name1 + ' ' + name2 def __setattr__(self, name, value): # 定义只读属性列表,这里只限制full_name read_only_attrs = {'full_name'} if name in read_only_attrs: raise AttributeError(f"无法修改只读属性 '{name}'") # 其他属性正常允许赋值 super().__setattr__(name, value) # 测试 name = Test('John','Watson') print(name.full_name) # 输出 'John Watson' name.full_name = 'someone else' # 触发错误:AttributeError: 无法修改只读属性 'full_name'
说明:
- 重写
__setattr__方法后,所有属性赋值都会经过这个方法,我们可以在这里判断是否是只读属性,若是则抛出错误。 - 初始化
full_name时必须用super().__setattr__,否则会触发自己的拦截逻辑导致初始化失败。
内容的提问来源于stack exchange,提问作者Leo Sam
相关产品推荐
相关产品推荐

