Python中可写属性(writable attribute)是什么?与其他属性有何区别?
Python中的可写属性是什么?和其他属性的区别
一、什么是可写属性
可写属性指的是能直接通过赋值操作(比如 obj.attr = value)修改、新增,或是通过 del 语句删除的对象实例属性。这类属性的存储与管理通常依赖对象的 __dict__ 字典——当你给实例添加或修改属性时,对应的键值对会被写入 __dict__;删除属性时则从 __dict__ 中移除对应键。
举个简单示例:
class Person: pass p = Person() p.name = "Alice" # 新增可写属性,存入p.__dict__ p.age = 30 # 修改/新增可写属性 del p.age # 删除属性,从p.__dict__中移除'age' print(p.__dict__) # 输出: {'name': 'Alice'}
二、与其他类型属性的核心区别
1. 和只读属性的区别
只读属性无法通过直接赋值修改,通常是类通过特殊方法(如 __getattr__、__getattribute__)或描述器实现的“仅可访问”属性,不会被存入 __dict__。比如Python内置不可变类型的属性:
s = "hello" s.length = 5 # 报错:str对象不支持属性赋值,因为str无__dict__且属性多为只读
2. 和类属性的区别
类属性属于类本身,存储在类的 __dict__ 中,而非实例的 __dict__。当实例没有同名可写属性时,会向上读取类属性;但如果给实例赋值同名属性,会在实例 __dict__ 中创建一个可写的实例属性,覆盖类属性的访问优先级:
class Person: species = "Human" # 类属性,存在Person.__dict__ p = Person() print(p.species) # 输出: Human(读取类属性) p.species = "Alien" # 创建实例可写属性,存入p.__dict__ print(p.species) # 输出: Alien(读取实例__dict__中的属性) print(Person.species) # 输出: Human(类属性未被修改)
3. 和描述器属性的区别
描述器属性(比如用 property 装饰器定义的属性)通过 __get__、__set__、__delete__ 方法控制访问逻辑,不会直接存入实例的 __dict__。如果描述器未实现 __set__ 方法则为只读;若实现了,赋值操作会触发 __set__ 方法,而非直接写入 __dict__:
class Person: def __init__(self): self._age = 20 @property def age(self): return self._age @age.setter def age(self, value): if value < 0: raise ValueError("Age can't be negative") self._age = value p = Person() p.age = 30 # 触发age.setter,修改的是self._age,而非写入p.__dict__['age'] print(p.__dict__) # 输出: {'_age': 30},无'age'键
4. 和__slots__限制属性的区别
如果类定义了 __slots__,实例默认不会生成 __dict__(除非 __slots__ 包含 '__dict__'),此时只有 __slots__ 中声明的属性可被赋值,这些属性虽可写,但不会存入 __dict__:
class Person: __slots__ = ('name', 'age') p = Person() p.name = "Bob" print(p.__dict__) # 报错:'Person' object has no attribute '__dict__'
内容的提问来源于stack exchange,提问作者user11909157
相关产品推荐
相关产品推荐

