一文详述 Python 中的 property 语法

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 语法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python黑魔法@property装饰器的使用技巧解析

    @property有什么用呢?表面看来,就是将一个方法用属性的方式来访问. 上代码,代码最清晰了. class Circle(object): def __init__(self, radius): self.radius = radius @property def area(self): return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.area 可以看到,area虽然是定义成一个方法的形式,但是加上@pr

  • Python中用Descriptor实现类级属性(Property)详解

    上篇文章简单介绍了python中描述器(Descriptor)的概念和使用,有心的同学估计已经Get√了该技能.本篇文章通过一个Descriptor的使用场景再次给出一个案例,让不了解情况的同学可以更容易理解. 先说说decorator 这两个单词确实是有些相似,同时在使用中也是形影不离.这也给人造成了理解上的困难,说装饰器和描述器到底是怎么回事,为什么非得用一个@符号再加上描述器才行. 很多文章也都把这俩结合着讲,我自己看完之后都会觉得很绕.其实学习一个知识点,和做项目开发一个功能是一样的.在

  • 介绍Python的@property装饰器的用法

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑.为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: class Student(object): def get_score(self): return self._score def set_s

  • python @property的用法及含义全面解析

    在接触python时最开始接触的代码,取长方形的长和宽,定义一个长方形类,然后设置长方形的长宽属性,通过实例化的方式调用长和宽,像如下代码一样. class Rectangle(object): def __init__(self): self.width =10 self.height=20 r=Rectangle() print(r.width,r.height) 此时输出结果为10 20 但是这样在实际使用中会产生一个严重的问题,__init__ 中定义的属性是可变的,换句话说,是使用一个

  • 实例讲解Python编程中@property装饰器的用法

    取值和赋值 class Actress(): def __init__(self): self.name = 'TianXin' self.age = 5 类Actress中有两个成员变量name和age.在外部对类的成员变量的操作,主要包括取值和赋值.简单的取值操作是x=object.var,简单的赋值操作是object.var=value. >>> actress = Actress() >>> actress.name #取值操作 'TianXin' >&g

  • Python解析json之ValueError: Expecting property name enclosed in double quotes: line 1 column 2(char 1)

    前言 在Python中提供了json包来方便快捷的解析json字串的转换过程,但是碰到了一个比较奇怪的问题,就是不太正确的json串如何来解析? 1. 问题的提出 今天在处理一个http请求的响应json之时,基于python进行解析,碰到了如下错误: Traceback (most recent call last): File "<ipython-input-16-bff463ed9408>", line 1, in <module> json.loads(

  • 一文详述 Python 中的 property 语法

    property() 函数的作用是在新式类中返回属性值. Python中有一个property的语法,它类似于C#的get set语法,其功能有以下两点: 将类方法设置为只读属性: 实现属性的getter和setter方法: 下面开始本文的重点介绍,Python 中的 property 语法介绍,具体内容如下所示: 在大多数语言的程序中,一个类,每有一个属性,就会对应 setter 和 getter,基本都是标配. 示例: class Money(object): def __init__(se

  • 一文秒懂Python中的字符串

    摘要:本文将告诉您Python中的字符串是什么,并向您简要介绍有关该概念的所有知识. 因此,让我们开始吧. 什么是Python中的字符串? 我们许多熟悉C,C ++等编程语言的人都会得到诸如"字符串是字符的集合或字符数组"的答案. 在Python中也是如此,我们说的是String数据类型的相同定义.字符串是序列字符的数组,并写在单引号,双引号或三引号内.另外,Python没有字符数据类型,因此当我们编写" a"时,它将被视为长度为1的字符串. 继续本文,了解什么是P

  • 一文秒懂python中的 \r 与 end=‘’ 巧妙用法

    /r的用法与end=""用法 \r 表示将光标的位置回退到本行的开头位置 end="" 意思是末尾不换行 在python里面,print()函数默认换行,即默认参数end = '\n' for i in range(3): print("Hello World") 可以设置print()函数的参数end=''",从而实现不换行 for i in range(3): print("Hello World", end=&

  • python中关于property的最详细使用方法

    为什么要写这篇文章 其实是因为最近学到了python的property装饰器的相关知识,刚开始学得云里雾里,于是乎,看了许多相关博客,不巧,大概是自己基础不太好吧,真心感觉许多人写的太过深奥,而且不是很全面.于是本人花了整整一下午实验,现在将关于property的相关知识分享出来.如有错误之处,还望各位不吝赐教! 什么是property装饰器 顾名思义,这是一个装饰器,起到一个辅助作用,具体理解请看下面一个例子.我们知道,程序中有许多变量都有范围的限制,比如年龄,工资,身高等不可能为负数.但是用

  • Python中关于property使用的小技巧

    目录 property属性 具体实例 property属性的有两种方式 装饰器方式 旧式类 新式类 类属性方式 property对象与@property装饰器对比 property对象类属性 @property装饰器 property属性 一种用起来像是使用实例属性一样的特殊属性,可以对应于某个方法 既要保护类的封装特性,又要让开发者可以使用 对象.属性 的方式操作方法,@property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对 () 小括号. 来看下求圆的面积的例子 c

  • Python中字符串对象语法分享

    目录 一.字符串的外观 1.字符串字面量 2.字符串与多行注释 3.字符串编码方式 二.字符串对象 1.str 2.str实现原理 3.str中的内置方法 4.字符串切片 前言:前面提到了Python中的数值型内置数据类型,接下来呢我们就着重介绍一下字符串类型.在Python中字符串是一个有序的字符集合,没有独立的字符数据类型,当字符串长度为1时就可以认为其是字符.Python的内置数据类型str用于字符串处理.str对象的值为字符系列字符串是不可变序列. 一.字符串的外观 1.字符串字面量 顾

  • python中的property及属性与特性之间的优先权

    目录 前言 属性(attribute) 属性的定义 属性的用法 特性(property) 特性的定义 特性的用法 特性的使用场景 属性和特性之间的差别和联系 属性和特性之间的优先权 前言 这几天看<流畅的python>这本书了,在一个示例中又看到了property作为装饰器在使用,因为很久没有用这个东西了,对它的一些特性和使用方法等都不是很熟悉,所以又专门在搜了几篇博客和在官方文档中学习了它的相关用法.再者又刚好学到了python中的属性(attribute),所以刚好这两者可以两相对比,也许

  • 一文掌握python中的时间包

    目录 python中的时间包 datetime时间包 获取当前时间 获取时间间隔 时间对象转时间字符串 时间字符串转时间对象 扩展–时间格式字符 时间戳–timestamp time时间包 获取当前时间戳 获取本地时间 暂停函数sleep time中的strftime和strptime python中的时间包 datetime时间包 datetime包是日期与时间的结合体(date&time) 可以获取当前时间 可以获取时间间隔 可以将时间对象转换成时间字符串 可以将字符串转成时间类型 导入da

  • Python中的特殊语法:filter、map、reduce、lambda介绍

    filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回: 复制代码 代码如下: >>> def f(x): return x % 2 != 0 and x % 3 != 0 >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] >>

  • python 中的@property的用法详解

    目录 1.什么是property 2.property属性定义的两种方式 3.用property代替getter和setter方法 1.什么是property 简单地说就是一个类里面的方法一旦被@property装饰,就可以像调用属性一样地去调用这个方法,它能够简化调用者获取数据的流程,而且不用担心将属性暴露出来,有人对其进行赋值操作(避免使用者的不合理操作).需要注意的两点是 调用被装饰方法的时候是不用加括号的 方法定义的时候有且只能有self一个参数 >>> class Goods(

随机推荐