66 类的 property 特性

676次阅读
没有评论

共计 2453 个字符,预计需要花费 7 分钟才能阅读完成。

一. 特性 property

1. 什么是 property 特性

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

66 类的 property 特性

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
正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计2453字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)