Python基础-面向对象编程之特性(property)

Python面向对象编程之特性(property)

一、统一访问原则

通常,我们访问实例或类的属性时,将返回所存储的相关值。而特性(property)是一种特殊的属性,访问它时会计算它的值。

请看下面的例子:

import math

class Circle():
  def __init__(self, radius):
    self.radius = radius  # 保存半径

  # Circle的一些附加特性
  
  @property
  def area(self):
    return math.pi * self.radius**2

  @property
  def perimeter(self):
    return 2 * math.pi * self.radius

if __name__ == '__main__':
  c = Circle(4.0)
  print(f'圆的半径为:{c.radius}')
  print(f'圆的面积为:{c.area}')
  print(f'圆的周长为:{c.perimeter}')

运行效果如下:

20221126005942

从这个例子中,我们可以看到,Circle实例存储了一个变量c.radius。而c.area和c.perimeter是根据该值计算得来的。@property装饰器支持以简单属性的形式访问后面的方法,无需像平时一样添加额外的()来调用该方法。对象的使用者很难发现正在计算一个属性,除非在试图重新定义该属性时生成了错误消息。

这种特性使用方式遵循所谓的统一访问原则。实际上,如果定义一个类,尽可能保持编程接口的统一总是不错的。如果没有特性(property),将会以简单属性(如c.radius)的形式访问对象的某些属性,而其他属性将以方法(如c.area())的形式进行访问。费力去了解何时添加额外的()会带来不必要的混淆。而特性可以解决此问题。

二、使用特性进行拦截操作

特性(property)还可以拦截操作,以设置和删除属性。这是通过向特性附加其他的setter和deleter方法来实现的,比如下面的代码:

class Foo():
  def __init__(self, name):
    self.__name = name

  @property
  def name(self):
    return self.__name

  @name.setter
  def name(self, value):
    if not isinstance(value, str):
      raise TypeError('must be a string')
    self.__name = value

  @name.deleter
  def name(self):
    raise TypeError('cannot delete name')

f = Foo('lilei')
n = f.name            # 调用f.name() get函数
f.name = 'hanmeimei'  # 调用setter name(f, 'hanmeimei')
f.name = 14           # 调用setter name(f, 45)  -> TypeError
del f.name            # 调用deleter name(f)     -> TypeError

在这个例子中,实现使用@property装饰器和相关方法将属性name定义为只读特性。后面的@name.setter和@name.deleter装饰器将其他方法与name属性上的设置和删除操作相关联。这些方法的名称必须与原始特性的名称完全匹配。在这些方法中,请注意实际的名称值是存储在属性self.__name中。所存储属性的名称无需遵循任何约定,但它必须与特性名称不同,以便将它与特性的名称区分开来。

三、老式写法

以前的老代码中可能还会看到以下这种写法:

class Foo():
  def getname(self):
    return self.__name

  def setname(self, value):
    self.__name = value

  def delname(self):
    raise TypeError('cannot delete name')

  name = property(getname, setname, delname)

这种老的写法仍然可用,但新的装饰器版本会让类看起来更完美一些。例如,如果使用装饰器,get、set、delete这些函数将不会显示为方法。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

smart_cat

你的鼓励将是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值