通过实例了解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使用pyhook监控键盘并实现切换歌曲的功能
Jul 18 Python
Python 冒泡,选择,插入排序使用实例
Feb 05 Python
Python新手在作用域方面经常容易碰到的问题
Apr 03 Python
儿童学习python的一些小技巧
May 27 Python
pytorch使用Variable实现线性回归
May 21 Python
python flask搭建web应用教程
Nov 19 Python
Python之Matplotlib文字与注释的使用方法
Jun 18 Python
Python实现自动签到脚本功能
Aug 20 Python
Python实现FTP文件定时自动下载的步骤
Dec 19 Python
Python爬虫入门教程01之爬取豆瓣Top电影
Jan 24 Python
python opencv人脸识别考勤系统的完整源码
Apr 26 Python
pytorch 带batch的tensor类型图像显示操作
May 20 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或asp创建网页桌面快捷方式的代码
2010/03/23 PHP
PHP中使用FFMPEG获取视频缩略图和视频总时长实例
2014/05/04 PHP
PHP两种去掉数组重复值的方法比较
2014/06/19 PHP
PHP获取某个月最大天数(最后一天)的方法
2015/07/29 PHP
PHP二维数组去重实例分析
2016/11/18 PHP
JavaScript 数组运用实现代码
2010/04/13 Javascript
精通Javascript系列之数据类型 字符串
2011/06/08 Javascript
js document.write()使用介绍
2014/02/21 Javascript
JavaScript使用DeviceOne开发实战(三)仿微信应用
2015/12/02 Javascript
jquery实现二级导航下拉菜单效果
2015/12/18 Javascript
Bootstrap教程JS插件滚动监听学习笔记分享
2016/05/18 Javascript
JS简单随机数生成方法
2016/09/05 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
jQuery展示表格点击变色、全选、删除
2017/01/05 Javascript
MvcPager分页控件 适用于Bootstrap
2017/06/03 Javascript
浅谈Node Inspector 代理实现
2017/10/19 Javascript
vue组件实现可搜索下拉框扩展
2020/10/23 Javascript
ES6与CommonJS中的模块处理的区别
2018/06/13 Javascript
vue组件表单数据回显验证及提交的实例代码
2018/08/30 Javascript
解决Vue2.0 watch对象属性变化监听不到的问题
2018/09/11 Javascript
angularJS1 url中携带参数的获取方法
2018/10/09 Javascript
微信小程序实现购物页面左右联动
2019/02/15 Javascript
python中类的一些方法分析
2014/09/25 Python
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
django修改models重建数据库的操作
2020/03/31 Python
python如何实现word批量转HTML
2020/09/30 Python
利用html5 canvas破解简单验证码及getImageData接口应用
2013/01/25 HTML / CSS
2019年c语言经典面试题目
2016/08/17 面试题
什么是makefile? 如何编写makefile?
2013/01/02 面试题
专科毕业生就业推荐信
2013/11/01 职场文书
关于建议书的格式范文
2014/05/20 职场文书
2014教师研修学习体会
2014/07/08 职场文书
孩子满月酒答谢词
2015/09/30 职场文书
九年级化学教学反思
2016/02/22 职场文书
用基于python的appium爬取b站直播消费记录
2021/04/17 Python