关于python中 !@property的使用

本文深入探讨了Python中@property装饰器的使用,解释了如何通过它实现对类属性的封装,确保属性值的有效性,同时保持代码的简洁性和可读性。

转自本文

python中 @property

考察 Student 类:

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

当我们想要修改一个 Student 的 scroe 属性时,可以这么写:

s = Student('Bob', 59)
s.score = 60

但是也可以这么写:

s.score = 1000

显然,直接给属性赋值无法检查分数的有效性。

如果利用两个方法:

复制代码

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    def get_score(self):
        return self.__score
    def set_score(self, score):
        if score < 0 or score > 100:
            raise ValueError('invalid score')
        self.__score = score

复制代码

这样一来,s.set_score(1000) 就会报错。

这种使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。

但是写 s.get_score() 和 s.set_score() 没有直接写 s.score 来得直接。

有没有两全其美的方法?----有。

因为Python支持高阶函数,可以用装饰器函数把 get/set 方法“装饰”成属性调用:

复制代码

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    @property
    def score(self):
        return self.__score
    @score.setter
    def score(self, score):
        if score < 0 or score > 100:
            raise ValueError('invalid score')
        self.__score = score

复制代码

注意: 第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。

现在,就可以像使用属性一样设置score了:

复制代码

>>> s = Student('Bob', 59)
>>> s.score = 60
>>> print s.score
60
>>> s.score = 1000
Traceback (most recent call last):
  ...
ValueError: invalid score

复制代码

说明对 score 赋值实际调用的是 set方法。

来源:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

 

内容概要:本文介绍了一个基于冠豪猪优化算法(CPO)的无人机三维路径规划项目,利用Python实现了在复杂三维环境中为无人机规划安全、高效、低能耗飞行路径的完整解决方案。项目涵盖空间环境建模、无人机动力学约束、路径编码、多目标代价函数设计以及CPO算法的核心实现。通过体素网格建模、动态障碍物处理、路径平滑技术和多约束融合机制,系统能够在高维、密集障碍环境下快速搜索出满足飞行可行性、安全性与能效最优的路径,并支持在线重规划以适应动态环境变化。文中还提供了关键模块的代码示例,包括环境建模、路径评估和CPO优化流程。; 适合人群:具备一定Python编程基础和优化算法基础知识,从事无人机、智能机器人、路径规划或智能优化算法研究的相关科研人员与工程技术人员,尤其适合研究生及有一定工作经验的研发工程师。; 使用场景及目标:①应用于复杂三维环境下的无人机自主导航与避障;②研究智能优化算法(如CPO)在路径规划中的实际部署与性能优化;③实现多目标(路径最短、能耗最低、安全性最高)耦合条件下的工程化路径求解;④构建可扩展的智能无人系统决策框架。; 阅读建议:建议结合文中模型架构与代码示例进行实践运行,重点关注目标函数设计、CPO算法改进策略与约束处理机制,宜在仿真环境中测试不同场景以深入理解算法行为与系统鲁棒性。
<think>我们正在讨论Python中的@property装饰器。根据引用,@property装饰器用于将方法转换为属性,使得可以像访问属性一样调用方法,同时还可以添加getter、setter和deleter方法以控制对属性的访问。功能:1.将方法转换为只读属性(通过@property装饰器)2.允许为属性设置setter(使用@属性名.setter)和deleter(使用@属性名.deleter)方法,从而在设置或删除属性时执行自定义逻辑。使用方法:1.定义一个方法,并用@property装饰。2.如果需要设置属性,则定义一个setter方法,使用@<property_name>.setter装饰。3.如果需要删除属性,则定义一个deleter方法,使用@<property_name>.deleter装饰。例子:下面我们创建一个Person类,其中有一个属性name,我们使用@property来控制对name的访问、设置和删除。注意:通常我们使用一个下划线前缀(如_name)来表示一个受保护的属性,这样我们就可以通过property来管理对它的访问。我们将按照以下步骤:1.使用@property装饰name方法,使其成为getter。2.使用@name.setter装饰一个方法,用于设置name。3.使用@name.deleter装饰一个方法,用于删除name。这样,当我们通过实例访问name时,会调用getter方法;当给name赋值时,会调用setter方法;当删除name时,会调用deleter方法。下面是一个具体的例子:</think>### Python @property 装饰器详解 #### 基本功能 `@property` 是 Python 的内置装饰器,用于将方法转换为**只读属性**。它的核心作用包括: 1. **封装性**:通过方法控制属性访问 2. **语法简化**:调用时像访问属性(`obj.prop`)而非方法(`obj.prop()`) 3. **数据验证**:在属性赋值时执行校验逻辑 4. **延迟计算**:属性值在访问时动态计算 --- #### 使用方法与示例 ##### 基础用法(只读属性) ```python class Circle: def __init__(self, radius): self._radius = radius # 使用下划线表示受保护属性 @property def area(self): """动态计算圆的面积""" print("计算面积中...") return 3.14 * self._radius ** 2 # 使用示例 c = Circle(5) print(c.area) # 输出: 计算面积中... \n 78.5 # c.area = 50 # 报错: AttributeError(只读属性) ``` ##### 完整属性控制(getter/setter/deleter) ```python class Person: def __init__(self, name): self._name = name @property def name(self): """Getter:访问时添加问候语""" print("获取姓名") return f"你好, {self._name}" @name.setter def name(self, value): """Setter:赋值时验证长度""" print("设置姓名") if len(value) < 2: raise ValueError("姓名至少2个字符") self._name = value @name.deleter def name(self): """Deleter:删除时记录日志""" print("删除姓名") self._name = None # 使用示例 p = Person("张三") print(p.name) # 输出: 获取姓名 \n 你好, 张三 p.name = "李四" # 输出: 设置姓名 del p.name # 输出: 删除姓名 ``` ##### 动态计算属性 ```python class Temperature: def __init__(self, celsius): self._celsius = celsius @property def fahrenheit(self): """摄氏转华氏""" return (self._celsius * 9/5) + 32 @fahrenheit.setter def fahrenheit(self, value): """华氏转摄氏""" self._celsius = (value - 32) * 5/9 # 使用示例 t = Temperature(0) print(t.fahrenheit) # 输出: 32.0 t.fahrenheit = 100 print(t._celsius) # 输出: 37.777... ``` --- #### 核心优势 1. **向后兼容**:添加属性逻辑不影响现有代码 2. **数据校验**:确保属性值有效性(如类型/范围检查) 3. **访问控制**:实现只读/私有属性 4. **调试友好**:可在 getter/setter 中添加日志或断点 > 注意:使用 `@property` 时应避免**昂贵计算**,因其每次访问都会执行方法体。对于计算密集型操作,建议使用缓存机制[^1][^2][^3][^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值