一文详述 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使用str & repr转换字符串
Oct 13 Python
Tensorflow环境搭建的方法步骤
Feb 07 Python
单利模式及python实现方式详解
Mar 20 Python
python微信撤回监测代码
Apr 29 Python
python 一个figure上显示多个图像的实例
Jul 08 Python
Django 实现图片上传和显示过程详解
Jul 18 Python
简单了解django缓存方式及配置
Jul 19 Python
解决python DataFrame 打印结果不换行问题
Apr 09 Python
Django中和时区相关的安全问题详解
Oct 12 Python
Pycharm操作Git及GitHub的步骤详解
Oct 27 Python
详解Python遍历列表时删除元素的正确做法
Jan 07 Python
SpringBoot首页设置解析(推荐)
Feb 11 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
星际原理概述
2020/03/04 星际争霸
用PHP和ACCESS写聊天室(三)
2006/10/09 PHP
PHP 登录完成后如何跳转上一访问页面
2014/01/14 PHP
php获取访问者IP地址汇总
2015/04/24 PHP
php实现word转html的方法
2016/01/22 PHP
php简单备份与还原MySql的方法
2016/05/09 PHP
xml 封装与解析(javascript和C#中)
2009/07/26 Javascript
Javascript笔记一 js以及json基础使用说明
2010/05/22 Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
2010/11/05 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
node.js中的buffer.copy方法使用说明
2014/12/14 Javascript
JavaScrip调试技巧之断点调试
2015/10/22 Javascript
实例详解angularjs和ajax的结合使用
2015/10/22 Javascript
jQuery中$.grep() 过滤函数 数组过滤
2016/11/22 Javascript
JavaScript中如何判断一个值的类型
2017/09/15 Javascript
JavaScript中Require调用js的实例分享
2017/10/27 Javascript
vue-cli 打包后提交到线上出现 "Uncaught SyntaxError:Unexpected token" 报错
2018/11/06 Javascript
mpvue性能优化实战技巧(小结)
2019/04/17 Javascript
微信公众号平台接口开发 菜单管理的实现
2019/08/14 Javascript
js通过canvas生成图片缩略图
2020/10/02 Javascript
JavaScript实现下拉列表
2021/01/20 Javascript
浅谈Python中的私有变量
2018/02/28 Python
Python调用adb命令实现对多台设备同时进行reboot的方法
2018/10/15 Python
python爬虫 模拟登录人人网过程解析
2019/07/31 Python
使用pandas库对csv文件进行筛选保存
2020/05/25 Python
CSS的pointer-events属性详细介绍(作用和注意事项)
2014/04/23 HTML / CSS
html5使用canvas画一条线
2014/12/15 HTML / CSS
全球知名提供各类营养保健品的零售商:Vitamin Shoppe
2016/10/09 全球购物
幼儿园师德师风学习材料
2014/05/29 职场文书
城市创卫标语
2014/06/17 职场文书
领导班子对照检查材料
2014/09/22 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
同学聚会祝酒词
2015/08/10 职场文书
Python中相见恨晚的技巧
2021/04/13 Python
JS不要再到处使用绝对等于运算符了
2021/04/30 Javascript
青岛市的收音机研制与生产
2022/04/07 无线电