🍖类的 property 特性

一.特性 property

1.什么是 property 特性

property 装饰器可以用于装饰类里面的方法, 让其伪装成一个数据属性, 也就是在调用的时候可以不用加括号

v2-878d130f7db8314bf8eac78484d68fb3

2.定义一个 property 特性

class Person:
    def run(self):
        print("小王在跑")

    @property  # 定义property属性
    def speak(self):
        print("李白在说话")

P1= Person()

P1.run()  # 小王在跑
P1.speak  # 李白在说话 (调用property属性)

3.为什么要有 property 特性

  • 将类的一个函数(方法)定义成 property 特性之后, 不加括号的去使用 [对象].[方法] 的时候, 我们无法察觉自己是执行了一个函数(方法), 这种特性的使用方式遵循了统一访问的原则

4.property 属性的定义和调用的注意点

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

二.property 属性的使用两种方法

1.第一种 : 使用 property( ) 函数 (古老用法, 了解即可)

class Person:
    def __init__(self):
        self.__name= None

    #这是setter方法
    def set_name(self,name):
        print("设置了名字")
        self.__name=name

    #这是getter方法
    def get_name(self):
        print("获取了名字")
        return self.__name

    # 这是deleter方法
    def del_name(self):
        print("删除了名字")
        del self.__name

    name=property(get_name,set_name,del_name) # 这里存放的是"name"的所有操作

P1 = Person()

P1.name = 'Shawn'  # 设置了名字 (直接赋值,等同于 P1.set_name('Shawn'))
n = P1.name        # 获取了名字 (直接获取数据 ,等同于 P1.get_name())
print(n)           # Shawn
del P1.name        # 删除了名字 (删除属性)
print(P1.name)     # 属性被删除了, 再次查看报错 : "AttributeError" 没有该属性

2.第二种 : 使用 @property 装饰器 (新方法)

  • 第二种方法 getter 必须写在 setter 和 deleter 的前面 (说是这么说, 但是实验了一下可以写在后面)
  • @property 装饰器必须写在 三者最前面, 并且三者都必须使用被@property修饰的同一个函数名, 否则报错
class Person:
    def __init__(self):
        self.__name= None

    @property 
    def name(self):       # 获取
        print("设置了名字")
        return self.__name

    @name.setter
    def name(self,name): # 设置
        print("设置名字成功")
        self.__name=name

    @name.deleter        # 删除
    def name(self):
        print("删除了名字")
        del self.__name

    @name.getter         # 获取
    def name(self):
        print("查看了名字并+'哈哈'")
        return self.__name + "哈哈"

P1 = Person()
P1.name = "shawn"  # 设置名字成功
n = P1.name        # 查看了名字并+'哈哈'
print(n)           # shawn哈哈

由上面的例子实验, 我们可以发现一个问题: @property 下修饰的功能其实是与 @name.getter 的功能重复的, 于是我们可以省略 @name.getter 不用写, 其实就是 @property 替代了 @name.getter

3.注意点

  • 经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
  • 新式类中的属性有三种访问方式,并分别对应了三个被 @property@方法名.setter@方法名.deleter 修饰的方法 (获取、修改、删除)

4.总结

  • 定义property属性共有两种方式,分别是装饰器类属性,而装饰器方式针对经典类和新式类又有所不同。
  • 通过使用property属性,能够简化调用者在获取数据的流程, 就是重新实现一个属性的设置和读取方法

三.property 特性的应用

1.property 与类的封装组合使用

其实上面的示例就是"property"特性与类的封装的组合使用

2.练习 : 计算圆的周长与面积

import math

class Circle:
    def __init__(self,radius):
        self.__radius = radius

    @property
    def area(self):
        return f"面积{math.pi * self.__radius ** 2}"

    @property
    def perimeter(self):
        return f"周长{2 * math.pi * self.__radius}"

C1 = Circle(10)
print(C1.area)      # 面积:314.1592653589793
print(C1.perimeter) # 周长:62.83185307179586

3.练习 : 计算BMI指数 (体质指数)

  • 利用身高与体重的比例来衡量一个人是否过瘦或过肥
  • 公式 : BMI = 体重(kg) / (身高(m) ** 2)
  • 范围 : (过轻:低于18.5), (正常:18.5-23.9), (过重:24-27), (肥胖:28-32), (非常肥胖, 高于32)
class Person:
    def __init__(self,weight,hight):
        self.__weight = weight
        self.__hight = hight

    @property
    def BMI(self):
        return f"BMI值 : {self.__weight / (self.__hight ** 2)}"

P1 = Person(56,1.73)
print(P1.BMI)  # BMI值 : 18.710949246550168
posted @ 2020-12-26 20:28  给你骨质唱疏松  阅读(184)  评论(0编辑  收藏  举报