通过实例了解python property属性


Posted in Python onNovember 01, 2019

这篇文章主要介绍了通过实例了解python property属性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

1. 什么是property属性

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

# ############### 定义 ###############
class Foo:
  def func(self):
    pass

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

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

如下的例子用于说明如何定一个简单的property属性:

class Goods(object):
    @property
    def size(self):
        return 100 
g = Goods()
print(g.size)

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

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

2. 简单的实例

对于京东商城中显示电脑主机的列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第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属性内部进行一系列的逻辑计算,最终将计算结果返回。

3. property属性的有两种方式

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

3.1 装饰器方式

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

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

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

# ############### 定义 ###############  
class Goods:
  @property
  def price(self):
    return "laowang"
# ############### 调用 ###############
obj = Goods()
result = obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
print(result)

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

#coding=utf-8
# ############### 定义 ###############
class Goods:
  """python3中默认继承object类
    以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
  """
  @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()
obj.price     # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123  # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
del obj.price   # 自动执行 @price.deleter 修饰的 price 方法

注意:

  • 经典类中的属性只有一种访问方式,其对应被 @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   # 删除商品原价

3.2 类属性方式,创建值为property对象的类属性

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

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

  BAR = property(get_bar)

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

property方法中有个四个参数

  • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
  • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
  • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
  • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息
#coding=utf-8
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()

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

由于类属性方式创建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属性,能够简化调用者在获取数据的流程

4. property属性-应用

4.1. 私有属性添加getter和setter方法

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:不是整型数字")

4.2. 使用property升级getter和setter方法

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:不是整型数字")

  # 定义一个属性,当对这个money设置值时调用setMoney,当获取值时调用getMoney
  money = property(getMoney, setMoney) 

a = Money()
a.money = 100 # 调用setMoney方法
print(a.money) # 调用getMoney方法
#100

4.3. 使用property取代getter和setter方法

重新实现一个属性的设置和读取方法,可做边界判定

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

  # 使用装饰器对money进行装饰,那么会自动添加一个叫money的属性,当调用获取money的值时,调用装饰的方法
  @property
  def money(self):
    return self.__money

  # 使用装饰器对money进行装饰,当对money设置值时,调用装饰的方法
  @money.setter
  def money(self, value):
    if isinstance(value, int):
      self.__money = value
    else:
      print("error:不是整型数字")

a = Money()
a.money = 100
print(a.money)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python的三目运算符和not in运算符使用示例
Mar 03 Python
pygame学习笔记(2):画点的三种方法和动画实例
Apr 15 Python
Pycharm远程调试openstack的方法
Nov 21 Python
Python构建网页爬虫原理分析
Dec 19 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
Aug 16 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
Aug 08 Python
Python如何实现小程序 无限求和平均
Feb 18 Python
Python新手学习函数默认参数设置
Jun 03 Python
如何用tempfile库创建python进程中的临时文件
Jan 28 Python
python3 hdf5文件 遍历代码
May 19 Python
python获取带有返回值的多线程
May 02 Python
Python使用openpyxl模块处理Excel文件
Jun 05 Python
python装饰器练习题及答案
Nov 01 #Python
Django框架HttpRequest对象用法实例分析
Nov 01 #Python
Django框架HttpResponse对象用法实例分析
Nov 01 #Python
Django框架序列化与反序列化操作详解
Nov 01 #Python
redis数据库及与python交互用法简单示例
Nov 01 #Python
python验证码图片处理(二值化)
Nov 01 #Python
使用matlab或python将txt文件转为excel表格
Nov 01 #Python
You might like
PHP管理内存函数 memory_get_usage()使用介绍
2012/09/23 PHP
php数组去除空值函数分享
2015/02/02 PHP
Yii实现的多级联动下拉菜单
2016/07/13 PHP
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
自制基于jQuery的智能提示插件一枚
2011/02/18 Javascript
计算世界完全对称日的js代码,粗糙版
2011/11/04 Javascript
邮箱下拉自动填充选择示例代码附图
2014/04/03 Javascript
简单介绍JavaScript的变量和数据类型
2015/06/03 Javascript
vue loadmore组件上拉加载更多功能示例代码
2017/07/19 Javascript
JS实现网页抢购功能(触发,终止脚本)
2017/11/27 Javascript
Vue中的无限加载vue-infinite-loading的方法
2018/04/08 Javascript
详解小程序中h5页面onShow实现及跨页面通信方案
2019/05/30 Javascript
Vue实现 点击显示再点击隐藏效果(点击页面空白区域也隐藏效果)
2020/01/16 Javascript
微信小程序使用前置摄像头拍照
2020/10/22 Javascript
python encode和decode的妙用
2009/09/02 Python
python中的内置函数getattr()介绍及示例
2014/07/20 Python
python中global用法实例分析
2015/04/30 Python
Python编程之多态用法实例详解
2015/05/19 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
2019/05/21 Python
Flask框架工厂函数用法实例分析
2019/05/25 Python
python opencv调用笔记本摄像头
2019/08/28 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
基于Python数据分析之pandas统计分析
2020/03/03 Python
python Tornado框架的使用示例
2020/10/19 Python
基于OpenCV的路面质量检测的实现
2020/11/04 Python
巧用CSS3的calc()宽度计算做响应模式布局的方法
2018/03/22 HTML / CSS
家得宝加拿大家装网上商店:The Home Depot加拿大
2016/08/27 全球购物
DVF官方网站:美国时装界尊尚品牌
2017/08/29 全球购物
某公司面试题
2012/03/05 面试题
Java Servlet的主要功能和作用是什么
2014/02/14 面试题
毕业生医学检验求职信
2013/10/16 职场文书
测绘工程个人的自我评价
2013/11/23 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书
基层干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
2014三年级班主任工作总结
2014/12/05 职场文书
粗暴解决CUDA out of memory的问题
2021/05/22 Python