网易首页 > 网易号 > 正文 申请入驻

Python 装饰器:@property

0
分享至

在 Python 的对象模型中,属性访问与方法调用共享统一的命名空间,但表达的语义却不同:属性描述对象的状态,方法表达对象的行为。随着类设计的演进,原本以属性公布的值可能需要延迟计算、加入校验逻辑、动态生成或与其他属性保持同步。

如果直接将属性改写为方法,不仅破坏既有的 API,还会使调用方式从:

obj.area

变为:

obj.area()

这种变化违背“接口稳定性”原则,不利于代码维护。

@property 应运而生,它可以将无参方法以属性形式呈现,使访问简单直观,但背后仍由方法控制逻辑,同时兼顾封装性、可扩展性和接口稳定性。

一、什么是 @property

@property 是 Python 内置的装饰器,用于将实例方法转换为描述符对象,使其在访问时触发自定义逻辑。其核心目标包括:

(1)提供优雅的属性访问语法

将方法逻辑以属性形式暴露,例如 obj.area 而不是 obj.area()。

(2)支持基于方法的动态计算或延迟求值

允许在属性访问时执行逻辑,而无需改变 API 约定。

(3)提升封装性

通过 getter、setter、deleter 控制属性的读取、赋值和删除行为。

(4)保持 API 的向后兼容

当原本的公开属性需要扩展逻辑时,可用 property 保持调用方式不变。

从 Pythonic 风格看,@property 是“显式优于隐晦”的体现:它让用户以简单的语法访问有逻辑支持的属性。

二、@property 工作原理

@property 的底层基于。

在 Python 中,任何实现以下方法之一的对象都被视为描述符:

__get__(self, instance, owner)

__set__(self, instance, value)

__delete__(self, instance)

描述符对象可以控制某个属性在 读取、写入、删除 时的行为。

property 本质是内置类:

    def __delete__(self, instance): ...

当我们定义:

        return ...

解释器会将 x 替换为一个 property 实例,其内部维护三个方法:

• fget:取值逻辑(getter)

• fset:赋值逻辑(setter)

• fdel:删除逻辑(deleter)

当执行:

obj.x

实际等价于:

A.x.__get__(obj, A)

即调用 fget(obj)。

类似地:

• 赋值 obj.x = value 等价于 A.x.__set__(obj, value)

• 删除 del obj.x 等价于 A.x.__delete__(obj)

因此,property 与简单属性不同,它是具有行为的托管属性。

三、核心方法:getter/setter/deleter

property 的三个核心组件共同构成完整的托管属性机制。

(1)getter:属性读取逻辑

最基本的 @property 用法是定义只读属性。

        return 3.14159 * self.r ** 2

使用:

print(c.area)     # 访问 area 属性时会自动调用其 getter(触发 fget 方法)

(2)setter:属性赋值逻辑

setter必须使用与 getter 同名的装饰器:

p.age = 20      # 访问 age 属性时会自动调用其 setter(触发 fset 方法)

说明:@age.setter 并不是随意命名,而是绑定到同一个 property 对象上,因此名称必须与 getter 相同。

(3)deleter:属性删除行为

用于资源释放或状态清理。

del res.conn   # 访问 conn 属性时会自动调用其 deleter(触发 fdel 方法)

说明:@conn.deleter 绑定的是同名 property 对象的删除逻辑方法,确保删除行为受控。

getter、setter 和 deleter 都必须保持与原 property 对象同名,确保访问行为受控。

四、典型应用场景

(1)将计算逻辑转换为自然的属性语法

当某个值由其他属性推导而来时,使用 property 会让 API 更自然。

        return self.w * self.h

用户角度:

rect.area   # 比 rect.area() 更直观

这是最常见的用法:用户访问属性时实际触发方法逻辑。

(2)为属性添加校验逻辑

避免直接暴露内部成员。

        self._c = value

(3)保持 API 向后兼容

当属性从简单值变成计算值时,不破坏调用方式。

初始版本中:

obj.speed = 12  # 简单属性

后来想加入单位转换或校验:

        self._speed = value

外部代码无需调整。

(4)隐藏内部实现,保护成员命名自由

有了 property 之后,可以随意修改内部成员名(如从 value → _value → _internal_value),让类具有更好的可维护性与扩展性。

五、常见误区

误区 1:在 getter 内访问自身属性导致无限递归

错误示例:

    return self.x   # 再次访问 property → 无限递归

正确写法:

    return self._x

误区 2:误认为 property 会自动缓存

每次访问都会重新计算。

如果需要缓存,应使用:

from functools import cached_property

误区 3:getter、setter 名称不一致

在使用 property 时,setter 方法必须绑定到同一个 property 对象上,因此名称必须与 getter 相同,否则不会生效:

    ...

误区 4:将 property 当作带参数的方法使用

property 只能表现为无参属性:

obj.value(3) # 错误

小结

@property 基于描述符协议实现,是 Python 中用于创建托管属性的核心机制。它让开发者以属性语法访问方法逻辑,在保持接口简洁的同时获得计算、校验与封装能力。通过 getter、setter 与 deleter,可以设计稳定且易维护的类接口。使用 property 时应避免递归访问、滥用复杂逻辑或错误绑定 setter,以保持类结构清晰、设计合理。


点赞有美意,赞赏是鼓励

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
今天才知道,为啥鹅蛋很少有人吃?为啥卖鹅蛋的人很少?涨知识

今天才知道,为啥鹅蛋很少有人吃?为啥卖鹅蛋的人很少?涨知识

阿龙美食记
2026-04-12 15:01:18
1955年,薄一波为何没出现在授衔名单中?假如参与,大将板上钉钉

1955年,薄一波为何没出现在授衔名单中?假如参与,大将板上钉钉

海佑讲史
2026-04-15 13:30:12
格列兹曼:第二个失球源于我丢了球权,我处理得太差了

格列兹曼:第二个失球源于我丢了球权,我处理得太差了

懂球帝
2026-04-15 06:16:06
体彩超级大乐透开出11注一等奖

体彩超级大乐透开出11注一等奖

吉刻新闻
2026-04-14 19:50:38
西安烤肉店闹剧:印度留学生跳着数串找茬,一句“滚回去”引热议

西安烤肉店闹剧:印度留学生跳着数串找茬,一句“滚回去”引热议

行者聊官
2026-04-14 16:20:36
婆婆3万买我9000万陪嫁房,我当即同意,半年后她悔不当初

婆婆3万买我9000万陪嫁房,我当即同意,半年后她悔不当初

奶茶麦子
2026-04-15 12:46:25
潜逃印度以贩卖艳照为生的女曱甴,拿BNO护照在中东被拒入境

潜逃印度以贩卖艳照为生的女曱甴,拿BNO护照在中东被拒入境

侠客栈
2026-04-14 11:36:31
1989年,85岁邓颖超,找到李鹏,开口就是5个字:我想安乐死

1989年,85岁邓颖超,找到李鹏,开口就是5个字:我想安乐死

玥来玥好讲故事
2026-04-13 20:54:18
原来温瑞博的爸爸是他!曾是乒乓球队顶梁柱,难怪19岁儿子这么牛

原来温瑞博的爸爸是他!曾是乒乓球队顶梁柱,难怪19岁儿子这么牛

林子说事
2026-04-15 11:34:09
丹麦男友去世后,东北姑娘仍为他生下遗腹子,还为了公婆定居丹麦

丹麦男友去世后,东北姑娘仍为他生下遗腹子,还为了公婆定居丹麦

星星没有你亮
2026-03-22 08:48:35
外媒:苏林对中国进行国事访问具有特殊意义

外媒:苏林对中国进行国事访问具有特殊意义

参考消息
2026-04-15 11:10:02
号称世界最好喝可乐单瓶售价29元 你会买单吗?

号称世界最好喝可乐单瓶售价29元 你会买单吗?

TechWeb
2026-04-15 12:33:05
陪玩陪睡算啥!继注射不明物后内娱又曝猛料,遭殃的何止迪丽热巴

陪玩陪睡算啥!继注射不明物后内娱又曝猛料,遭殃的何止迪丽热巴

草莓解说体育
2026-04-15 13:37:36
国务院825号令落地:终结电动车乱罚款,车主终于能安心上路了

国务院825号令落地:终结电动车乱罚款,车主终于能安心上路了

糖逗在娱乐
2026-04-15 12:00:42
哈里梅根空降澳洲开启巡演,当地民众冷脸开炮:真不明白他们来干嘛!

哈里梅根空降澳洲开启巡演,当地民众冷脸开炮:真不明白他们来干嘛!

动物奇奇怪怪
2026-04-15 01:07:49
苹果8号员工干了49年:裁员名单绕着他走,因为赔不起

苹果8号员工干了49年:裁员名单绕着他走,因为赔不起

世界圈
2026-04-04 13:13:03
徐杰的2+1判罚正确吗?裁判专家给出答案,球迷:不是2+1也属违体

徐杰的2+1判罚正确吗?裁判专家给出答案,球迷:不是2+1也属违体

南海浪花
2026-04-15 06:41:10
狂赚26亿、裁员近千人、惊动五部门的BOSS直聘,能横行到几时?

狂赚26亿、裁员近千人、惊动五部门的BOSS直聘,能横行到几时?

数智研究社
2026-04-15 07:30:07
15号午评:沪指早间红盘震荡!所有人都注意,大盘后市或将这样走

15号午评:沪指早间红盘震荡!所有人都注意,大盘后市或将这样走

春江财富
2026-04-15 11:55:27
特朗普突然对中国汽车加征100%关税,中方强硬反制

特朗普突然对中国汽车加征100%关税,中方强硬反制

冷峻视角下的世界
2026-04-15 13:20:17
2026-04-15 14:08:49
MediaTea
MediaTea
专业的数字媒体、新媒体技术
1826文章数 80关注度
往期回顾 全部

科技要闻

手机无死角上网?亚马逊砸百亿硬刚马斯克

头条要闻

上万美军封锁下 多艘货船成功通过霍尔木兹海峡

头条要闻

上万美军封锁下 多艘货船成功通过霍尔木兹海峡

体育要闻

三球准绝杀戴大金链:轰30+10自我救赎

娱乐要闻

曾志伟办73岁生日派对,逾百艺人到场

财经要闻

业绩失速的Lululemon:"健康"人设崩塌?

汽车要闻

海豹08内饰首秀 大满配“海王”旗舰

态度原创

教育
手机
本地
游戏
公开课

教育要闻

413、403、375分!文华学院这3个女孩同时上岸武汉体育学院!

手机要闻

为什么你玩游戏觉得不舒服 李杰:手机细节毁了体验

本地新闻

12吨巧克力有难,全网化身超级侦探添乱

这年头居然还有“扫雷”新作?肉鸽+战术DEMO上线

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版