一文详述 Python 中的 property 语法


Posted in Python onSeptember 01, 2020

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

Python中有一个property的语法,它类似于C#的get set语法,其功能有以下两点:

  • 将类方法设置为只读属性;
  • 实现属性的getter和setter方法;

下面开始本文的重点介绍,Python 中的 property 语法介绍,具体内容如下所示:

在大多数语言的程序中,一个类,每有一个属性,就会对应 setter 和 getter,基本都是标配。

示例:

class Money(object):
  def __init__(self):
    self.__money = 0

  def getMoney(self):
    return self.__money

  def setMoney(self, value):
    if isinstance(value, int):
      self.__money = value
    else:
      print("error:不是整型数字")

设置私有属性的目的就是不想让数据被误取出来,增加一个方法去获取私有属性或者设置私有属性,那么就保证将来想获取属性的时候就获取,想设置的时候还可以进行过滤。

其他语言基本都是这么做的,但是 Python 不推荐。 Python 有 property。

一、什么是property属性

一种用起来像是使用的实例属性一样的特殊属性,可以对应于某个方法。

class Foo:
  def func(self):
    pass

  # 定义property属性
  @property
  def prop(self):
    pass

foo_obj = Foo()
foo_obj.func() # 调用实例方法
foo_obj.prop # 调用property属性

示例:

class Goods:
  @property
  def size(self):
    return 100

obj = Goods()
ret = obj.size # 调用属性
print(ret) # 100

obj.size 会自动地去调用 size 方法,返回 size 方法的返回值。

property属性的定义和调用要注意以下几点:

  • 定义时,在实例方法的基础上添加 @property 装饰器;
  • 仅有一个self参数;
  • 调用时,无需括号。

那 property 属性到底是用来干什么的?下面看一个实例。

对于京东商城中显示电脑主机的列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据,这个分页的功能包括:

  • 根据用户请求的当前页和总数据条数计算出 m 和 n。
  • 根据m 和 n 去数据库中请求数据。
class Pager:
  def __init__(self, current_page):
    # 用户当前请求的页码(第一页、第二页...)
    self.current_page = current_page
    # 每页默认显示10条数据
    self.per_items = 10

  @property
  def start(self):
    val = (self.current_page - 1) * self.per_items
    return val

  @property
  def end(self):
    val = self.current_page * self.per_items
    return val

p = Pager(1)
p.start # 就是起始值,即:m
p.end # 就是结束值,即:n

从上述可见,Python 的 property 属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回。

二、property属性的有两种方式

  • 装饰器 即:在方法上应用装饰器。
  • 类属性 即:在类中定义值为 property 对象的类属性。

1、装饰器方式

在类的实例方法上应用 @property 装饰器。

Python中的类有经典类和新式类,新式类的属性比经典类的属性丰富。( 如果类继object,那么该类是新式类 )

经典类,具有一种 @property 装饰器。

class Goods:
  @property
  def price(self):
    return "laowang"

obj = Goods()
# 自动执行 @property 修饰的 price 方法,并获取方法的返回值
result = obj.price 
print(result) # laowang

新式类,具有三种@property装饰器。

python3 中默认继承object类,只有在 python3 中才有@xxx.setter @xxx.deleter。

class Goods:
  
  @property
  def price(self):
    print('@property')

  @price.setter
  def price(self, value):
    print('@price.setter')

  @price.deleter
  def price(self):
    print('@price.deleter')

obj = Goods()
# 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price # @property
# 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
obj.price = 123 # @price.setter
# 自动执行 @price.deleter 修饰的 price 方法
del obj.price # @price.deleter

注意:

  • 经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法。
  • 新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法。

由于新式类中具有三种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除。

示例:

class Goods(object):

  def __init__(self):
    # 原价
    self.original_price = 100
    # 折扣
    self.discount = 0.8

  @property
  def price(self):
    # 实际价格 = 原价 * 折扣
    new_price = self.original_price * self.discount
    return new_price

  @price.setter
  def price(self, value):
    self.original_price = value

  @price.deleter
  def price(self):
    del self.original_price

obj = Goods()
obj.price     # 获取商品价格
obj.price = 200  # 修改商品原价
del obj.price   # 删除商品原价

2、类属性方式

创建值为 property 对象的类属性。

当使用类属性的方式创建property属性时,经典类和新式类无区别。

示例:

class Foo:
  def get_bar(self):
    return 'laowang'

  BAR = property(get_bar)

obj = Foo()
reuslt = obj.BAR # 自动调用get_bar方法,并获取方法的返回值
print(reuslt) # laowang

property方法中有个四个参数

  • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法。
  • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法。
  • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法。第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息。

示例:

class Foo(object):
  def get_bar(self):
    print("getter...")
    return 'laowang'

  def set_bar(self, value):
    """必须两个参数"""
    print("setter...")
    return 'set value' + value

  def del_bar(self):
    print("deleter...")
    return 'laowang'

  BAR = property(get_bar, set_bar, del_bar, "description...")

obj = Foo()
# 自动调用第一个参数中定义的方法:get_bar
obj.BAR # getter...
# 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
obj.BAR = "alex" # setter...
# 自动获取第四个参数中设置的值:description...
desc = Foo.BAR.__doc__
print(desc) # description...
# 自动调用第三个参数中定义的方法:del_bar方法
del obj.BAR # deleter...

由于类属性方式创建 property 属性具有3种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除。

class Goods(object):

  def __init__(self):
    # 原价
    self.original_price = 100
    # 折扣
    self.discount = 0.8

  def get_price(self):
    # 实际价格 = 原价 * 折扣
    new_price = self.original_price * self.discount
    return new_price

  def set_price(self, value):
    self.original_price = value

  def del_price(self):
    del self.original_price

  PRICE = property(get_price, set_price, del_price, '价格属性描述...')

obj = Goods()
obj.PRICE     # 获取商品价格
obj.PRICE = 200  # 修改商品原价
del obj.PRICE   # 删除商品原价

综上所述:

  • 定义property属性共有两种方式,分别是【装饰器】和【类属性】,而【装饰器】方式针对经典类和新式类又有所不同。
  • 通过使用property属性,能够简化调用者在获取数据的流程。

总结

到此这篇关于一文详述 Python 中的 property 语法的文章就介绍到这了,更多相关Python 中的 property 语法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python使用稀疏矩阵节省内存实例
Jun 27 Python
Python map和reduce函数用法示例
Feb 26 Python
Tensorflow的可视化工具Tensorboard的初步使用详解
Feb 11 Python
Python自动发送邮件的方法实例总结
Dec 08 Python
Python图像处理库PIL的ImageGrab模块介绍详解
Feb 26 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
Mar 25 Python
django 获取字段最大值,最新的记录操作
Aug 09 Python
python爬虫基础之urllib的使用
Dec 31 Python
matlab xlabel位置的设置方式
May 21 Python
如何在C++中调用Python
May 21 Python
浅谈Python数学建模之数据导入
Jun 23 Python
Pygame Time时间控制的具体使用详解
Nov 17 Python
Python Opencv轮廓常用操作代码实例解析
Sep 01 #Python
聊聊python中的异常嵌套
Sep 01 #Python
理解Django 中Call Stack机制的小Demo
Sep 01 #Python
如何快速理解python的垃圾回收机制
Sep 01 #Python
Python Opencv图像处理基本操作代码详解
Aug 31 #Python
Python Matplotlib绘图基础知识代码解析
Aug 31 #Python
一些关于python 装饰器的个人理解
Aug 31 #Python
You might like
德生BCL3000的电路分析和打磨
2021/03/02 无线电
56.com视频采集接口程序(PHP)
2007/09/22 PHP
实现在同一方法中获取当前方法中新赋值的session值解决方法
2014/06/26 PHP
PHP统一页面编码避免乱码问题
2015/04/09 PHP
php arsort 数组降序排序详细介绍
2016/11/17 PHP
PHP编程实现csv文件导入mysql数据库的方法
2017/04/29 PHP
Yii输入正确验证码却验证失败的解决方法
2017/06/06 PHP
PHP递归实现快速排序的方法示例
2017/12/18 PHP
PhpStorm连接服务器并实现自动上传功能
2020/12/09 PHP
javascript实现的动态添加表单元素input,button等(appendChild)
2007/11/24 Javascript
jQuery 文本框得失焦点的简单实例
2014/02/19 Javascript
基于jQuery实现网页进度显示插件
2015/03/04 Javascript
基于jquery实现省市联动效果
2015/11/23 Javascript
laydate.js日期时间选择插件
2017/01/04 Javascript
Angular.js 4.x中表单Template-Driven Forms详解
2017/04/25 Javascript
微信小程序wx.request实现后台数据交互功能分析
2017/11/25 Javascript
bootstrap table实现横向合并与纵向合并
2019/07/18 Javascript
使用Vue实现调用接口加载页面初始数据
2019/10/28 Javascript
JS实现秒杀倒计时特效
2020/01/02 Javascript
微信小程序去除左上角返回键的实现方法
2020/03/06 Javascript
JS创建自定义对象的六种方法总结
2020/12/15 Javascript
[01:10]DOTA2次级职业联赛 - Fly战队宣传片
2014/12/01 DOTA
[10:14]2018DOTA2国际邀请赛寻真——paiN Gaming不仅为自己而战
2018/08/14 DOTA
pyqt4教程之widget使用示例分享
2014/03/07 Python
python 检查数据中是否有缺失值,删除缺失值的方式
2019/12/02 Python
appium+python adb常用命令分享
2020/03/06 Python
美国诺德斯特龙百货官网:Nordstrom
2016/08/23 全球购物
Windows和Linux动态库应用异同
2016/07/28 面试题
调研汇报材料范文
2014/08/17 职场文书
领导干部群众路线个人对照检查材料思想汇报
2014/09/30 职场文书
个人债务授权委托书范本
2014/10/05 职场文书
中学教师个人总结
2015/02/10 职场文书
师德承诺书2015
2015/04/28 职场文书
2015年幼儿园安全工作总结
2015/05/12 职场文书
深入浅出讲解Java8函数式编程
2022/01/18 Java/Android
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
2022/04/14 Python