Python装饰器@property详解:从基础到高级应用
原文地址: https://88box.top 生成时间: 2026-05-20 01:02:04
Python中的装饰器@property用法总结 - hey99 知识搜索引擎
精选文章
Python中的装饰器@property用法总结
property是Python实现“受控属性”的核心工具,既能让代码更简洁(方法属性化),又能灵活控制属性的读取、赋值和删除逻辑,广泛用于数据校验、动态计算、接口兼容等场景。
更新于 2026-05-19 16:47
文章目录
一、核心作用
二、基本用法
-
只读属性(仅获取)
-
可读可写属性(
@属性名.setter) -
可删除属性(
@属性名.deleter)
三、与普通属性的区别
四、高级应用场景
-
缓存计算结果
-
兼容旧接口
五、注意事项
总结
@property
是Python中的装饰器,用于将类的方法转换为
属性
(即“特性”),让方法可以像普通属性一样被访问和赋值,同时支持在访问/赋值时添加自定义逻辑(如数据校验、计算、缓存等),实现对属性的精细化控制。
一、核心作用
方法属性化
:将方法伪装成属性,调用时无需加括号(
obj.attr
而非
obj.attr()
);
控制访问逻辑
:在属性读取、赋值、删除时插入自定义代码(如校验、计算);
兼容原有接口
:在不修改外部调用方式的前提下,重构属性的实现逻辑。
二、基本用法
- 只读属性(仅获取)
将方法装饰为只读属性,实现“计算属性”(值动态生成)。
class
Circle
:
def
init
(
self
,
radius
)
:
self
.
radius
=
radius
@property
def
area
(
self
)
:
"""计算圆的面积(只读属性)"""
return
3.14159
*
self
.
radius
**
2
使用
c
=
Circle
(
5
)
(
c
.
area
)
无需加括号,直接访问 → 78.53975
c.area = 100 # 报错:无法赋值(只读)
- 可读可写属性(
@属性名.setter
)
通过
@属性名.setter
装饰器定义赋值逻辑,实现属性的写控制(如数据校验)。
class
Person
:
def
init
(
self
,
name
)
:
self
.
_name
=
name
私有变量(约定用下划线标识)
@property
def
name
(
self
)
:
"""获取name属性"""
return
self
.
_name
@name
.
setter
def
name
(
self
,
value
)
:
"""设置name属性(添加校验)"""
if
not
isinstance
(
value
,
str
)
:
raise
TypeError
(
"name必须是字符串"
)
if
len
(
value
)
<
2
:
raise
ValueError
(
"name长度不能小于2"
)
self
.
_name
=
value
使用
p
=
Person
(
"Alice"
)
(
p
.
name
)
获取 → Alice
p
.
name
=
"Bob"
赋值(触发setter)
(
p
.
name
)
Bob
p.name = 123 # 触发TypeError
p.name = "A" # 触发ValueError
- 可删除属性(
@属性名.deleter
)
通过
@属性名.deleter
装饰器定义删除逻辑,控制
del obj.attr
的行为。
class
Person
:
def
init
(
self
,
age
)
:
self
.
_age
=
age
@property
def
age
(
self
)
:
return
self
.
_age
@age
.
deleter
def
age
(
self
)
:
"""删除age属性时的逻辑"""
(
"删除age属性"
)
del
self
.
_age
使用
p
=
Person
(
25
)
del
p
.
age
触发deleter → 打印"删除age属性"
print(p.age) # 报错:_age已被删除
三、与普通属性的区别
特性
普通属性
@property
装饰的属性
访问方式
直接访问(
obj.attr
)
直接访问(
obj.attr
)
底层逻辑
简单赋值/读取
可嵌入自定义逻辑(校验、计算)
可变性
默认可读可写
可控制为只读/可写/可删除
动态性
固定值
可动态计算(如面积、年龄)
四、高级应用场景
- 缓存计算结果
对耗时的计算属性缓存结果,避免重复计算:
class
Rectangle
:
def
init
(
self
,
width
,
height
)
:
self
.
width
=
width
self
.
height
=
height
self
.
_area
=
None
缓存面积
@property
def
area
(
self
)
:
if
self
.
_area
is
None
:
(
"计算面积..."
)
self
.
_area
=
self
.
width
*
self
.
height
return
self
.
_area
使用
r
=
Rectangle
(
3
,
4
)
(
r
.
area
)
计算面积... → 12(首次计算并缓存)
(
r
.
area
)
12(直接读取缓存)
- 兼容旧接口
重构类时,将原有方法改为属性,不影响外部调用:
旧版本:通过方法获取姓名
class
User
:
def
get_name
(
self
)
:
return
self
.
_name
新版本:用@property兼容
class
User
:
def
init
(
self
,
name
)
:
self
.
_name
=
name
@property
def
name
(
self
)
:
return
self
.
_name
外部调用:从user.get_name()改为user.name,更简洁
五、注意事项
命名规范
:内部存储的变量通常用下划线开头(如
_name
),避免与
@property
装饰的属性名冲突;
只读属性
:仅定义
@property
而不定义
setter
,则属性为只读;
性能
:若属性逻辑复杂(如大量计算),需注意性能开销(可结合缓存);
与
dict
的关系
:
@property
定义的属性不会出现在实例的
dict
中(存储在类的
dict
)。
总结
@property
是Python实现“受控属性”的核心工具,既能让代码更简洁(方法属性化),又能灵活控制属性的读取、赋值和删除逻辑,广泛用于数据校验、动态计算、接口兼容等场景。
查看原文
🏷 标签: Python装饰器, property, 属性控制, 数据校验, 计算属性