通过实例了解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 判断自定义对象类型
Mar 21 Python
python实现获取序列中最小的几个元素
Sep 25 Python
python文件操作之目录遍历实例分析
May 20 Python
Python简单获取自身外网IP的方法
Sep 18 Python
详解python实现读取邮件数据并下载附件的实例
Aug 03 Python
pandas修改DataFrame列名的方法
Apr 08 Python
Python实现的生产者、消费者问题完整实例
May 30 Python
python验证码识别教程之利用投影法、连通域法分割图片
Jun 04 Python
在python中实现强制关闭线程的示例
Jan 22 Python
Python使用matplotlib绘制Logistic曲线操作示例
Nov 28 Python
Python编译为二进制so可执行文件实例
Dec 23 Python
python 实现定时任务的四种方式
Apr 01 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
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
PHP实现的构造sql语句类实例
2016/02/03 PHP
strpos() 函数判断字符串中是否包含某字符串的方法
2019/01/16 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
javascript原生和jquery库实现iframe自适应高度和宽度
2014/07/18 Javascript
javascript实现根据身份证号读取相关信息
2014/12/17 Javascript
jQuery控制Div拖拽效果完整实例分析
2015/04/15 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
2015/09/01 Javascript
原生js实现class的添加和删除简单代码
2016/07/12 Javascript
Javascript从数组中随机取出不同元素的两种方法
2016/09/22 Javascript
详解使用vue脚手架工具搭建vue-webpack项目
2017/05/10 Javascript
Javascript es7中比较实用的两个方法示例
2017/07/21 Javascript
深入浅析Vue全局组件与局部组件的区别
2018/06/15 Javascript
使用async await 封装 axios的方法
2018/07/09 Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
2018/07/10 Javascript
详解JWT token心得与使用实例
2019/08/02 Javascript
layui 动态设置checbox 选中状态的例子
2019/09/02 Javascript
vue实现输入一位数字转汉字功能
2019/12/13 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
浅谈vue.watch的触发条件是什么
2020/11/07 Javascript
利用JavaScript模拟京东按键输入功能
2020/12/01 Javascript
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
教大家使用Python SqlAlchemy
2016/02/12 Python
用Python将mysql数据导出成json的方法
2018/08/21 Python
浅谈python新式类和旧式类区别
2019/04/26 Python
Python csv模块使用方法代码实例
2019/08/29 Python
python给视频添加背景音乐并改变音量的具体方法
2020/07/19 Python
俄罗斯首家面向中国消费者的一站式购物网站:Wruru
2020/05/08 全球购物
实习单位接收函
2014/01/11 职场文书
2014年情人节活动方案
2014/02/16 职场文书
测控技术自荐信
2014/06/05 职场文书
民主评议党员自我鉴定
2014/10/21 职场文书
检讨书怎么写
2015/01/23 职场文书
2016年大学校运会广播稿件
2015/12/21 职场文书
2016银行招聘自荐信
2016/01/28 职场文书
Go 语言中 20 个占位符的整理
2021/10/16 Golang