写点什么

【Python 编程技巧】简单理解和使用 Python 中 @property

作者:迷彩
  • 2022 年 8 月 25 日
    广东
  • 本文字数:1846 字

    阅读完需:约 6 分钟

引言

如果你还学习过其他诸如 java,php 等面向对象编程语言的话,你会发现,其实 Python 面向对象跟其他的编程语言的面向对象基本是一样的,只是语言语法上的有些许的差别而已.Python 中的类同样包括类的属性和类的方法.同时一样也拥有面向对象的三大特征.接下来,我们先来看看本文的主角:Python 中有关于属性的概念

属性

实例属性:通过实例变量或 self 来定义.

类属性:定义在类中的属性.

私有属性:Python 面向对象的属性,可以更加方便地访问私有数据成员.


在 Python 中,可以通过 @property 将一个实例方法转换为同名属性,从而实现用于计算的属性.将方法转换为属性后,可以直接通过方法名来访问方法,而不需要再添加一对小括号"()",这样可以让代码更整洁.

语法如下:

@property

def methodnames(self):

statement block


参数说明如下:

  • methodnames:用于指定方法名.一般使用小写字母开头

  • self:表示类的实例

  • statement block:方法体,用于实现具体的功能,在方法体中,通常以 return 语句结束,用于返回计算结果.return 后面的语句一定不会执行

说明:通过 @property 转换后的属性不能重新赋值.如果对其重新赋值,将会抛出异常信息.通过 getter 和 setter 方法定义只读和修改属性,shiy@methodnames.getting 可以修饰新的实例方法,从而修改实例的属性.

实例讲解

可能光说概念比较抽象.不好理解.下面我们通过实例展开来学习,这样显得更加通俗易懂一点


简单地说,一个类里面的方法一旦被 @property 装饰,就可以像调用属性一样地去调用这个方法,它能够简化调用者获取数据的流程,而且不用担心将属性暴露出来,有人对其进行赋值操作(避免使用者的不合理操作)。需要注意的两点是:


  1. 调用被装饰方法的时候是不用加括号的

  2. 方法定义的时候有且只能有 self 一个参数

具体用法如下:

    @property    def password(self):        raise AttributeError('password is not a readable attribute')
@password.setter def password(self, password): self.password_hash = generate_password_hash(password)
复制代码

比如:在我们定义数据库字段类的时候,往往需要对其中的类属性做一些限制,一般用 get 和 set 方法来写,也就是 java 中的 bean;那在 python 中,我们该怎么做能够少写代码,既能优雅地实现想要的限制的同时,还能减少错误的发生呢

写法对比

没使用 @property 是这样写的:

class Employee(object):    def get_salary(self):        return self._salary
def set_salary(self, value): self._salary = value
s = Employee()s.set_salary(8000)print(s.get_salary())print("修改员工工资为:")s.set_salary(9999)
print(s.get_salary())
复制代码

使用 @property 是这样写的:

方法一
class Employee(object):    @property    def salary(self):        return self._salary
@salary.setter def salary(self, value): if value < 0: raise 'error:工资必须大于零' self._salary = value
s = Employee()s.salary = 8000print(s.salary)print("修改员工工资为:")s.salary = 18888
print(s.salary)
复制代码

执行结果:

把 get 方法变为属性只需要加上 @property 装饰器即可,此时 @property 本身又会创建另外一个装饰器 @salary.setter,负责把 set 方法变成给属性赋值,这样调用起来非常方便,代码的可读性也有所提高.然后通过调用属性的方式直接调用到 salary 方法,因为 @property 已经把复杂的处理过程封装到了方法里面去,这样在取值的时候调用相应的方法名即可

方法二

除了上面的写法,还可以使用 property() 函数来实现同样的功能,但是没有上面写法那么简单,因为还要书写 getter 和 setter 方法.然后再通过 property() 函数返回

property() 函数的作用是在新式类中返回属性值。

语法:

class property([fget[, fset[, fdel[, doc]]]])
复制代码

参数:一共有四个参数

  • fget -- 获取属性值的函数,调用 对象.属性时自动触发

  • fset -- 设置属性值的函数,给属性赋值时自动触发

  • fdel -- 删除属性值函数,删除属性时自动触发

  • doc -- 字符串类型,是属性的描述信息,调用对象.属性.doc 时触发

返回值:

返回新式类属性


废话不多说,直接上代码:

class Employee():    def __init__(self, salary=5000):        self._salary = salary
def get_salary(self): return self._salary
def set_salary(self, salary): self._salary = salary
def del_salary(self): del self._salary
a_sl = property(get_salary, set_salary)
s = Employee()s.a_sl=8000print(s.a_sl)print("修改员工工资为:")s.a_sl=9999
print(s.a_sl)
复制代码


发布于: 刚刚阅读数: 6
用户头像

迷彩

关注

我的工作是常年写bug|公众号:编程架构之美 2020.06.18 加入

修bug的菜鸟~公众号:“互联网有啥事”已改名为“编程架构之美”

评论

发布
暂无评论
【Python编程技巧】简单理解和使用Python中@property_@PropertySource_迷彩_InfoQ写作社区