python3:聊聊 为什么要有@property装饰器

版权声明:转载 或者复制请标注来源 https://blog.csdn.net/qq_34979346/article/details/83718252

这个章节大部分人都明白@property 的作用。
难道不是把方法转化成属性,可以直接赋值?

那我们说说为什么这么做有什么意义呢?

先用代码一点点引导。
1.避免直接赋值,绕过校验

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age


stu=Student("Lady",50)
prtint(stu.age)
stu.age=120
print(stu.age)

打印结果:

50
120

从上边结果看,可以随意读取和修改age并且设置的age还不符合年龄规范。
这显然不行。
首先我们想到的是 用方法加校验 并创建属性,并用方法获取。

class Student:
    def __init__(self,name):
        self.name=name
    def set_age(self,age):
        if isinstance(age,int):
            if 0<age<120:
                self.age=age
        else:
            print("请输入合法的年龄")
    def get_age(self):
        return self.age


stu=Student("Lady")
stu.age=120
print(stu.age)

打印结果;

120

上边的代码小伙伴该说了,我不用方法也可以修改值,
stu.age=120
print(stu.age)
并没有报错呀。

为了解释这个原因,我们直接打印这个属性。

print(stu.age)

报错如下:

 'Student' object has no attribute 'age'

之所以不会报错 关键点在 stu.age=120 这个步骤是实例化对象。
stu自己给自己添加了一个age 属性,所以不会报错。
这个属性只是属于stu,你换个实例再打印也一定会报错。扯的有点多了,
开始回到正轨。

class Student:
    def __init__(self,name):
        self.name=name
    def set_age(self,age):
        if isinstance(age,int):
            if 0<age<120:
                self.age=age
            else:
                print("请注意你的年龄范围")
        else:
            print("请输入合法的年龄")
    def get_age(self):
        return self.age


stu=Student("Lady")
stu.set_age(1110)    #输入不规范的年龄
stu.set_age(10)      #设置age,并通过一系列的校验
print(stu.age)       # 可以直接调用
print(stu.get_age())  #获取age

打印结果 :

请注意你的年龄范围
10
10

两种方法都可以取到age,
那小伙伴该说 我们就没有必要写get方法了,直接用stu.age调用就行了
(直接用了set 方法的返回值)

为了防止这种情况发生,规范如下;
set方法里面的返回的属性名前面加上 _,一个小短线。
(实际也不能避免,相对而言安全)
所以写成这样

class Student:
    def __init__(self,name):
        self.name=name
    def set_age(self,age):
        if isinstance(age,int):
            if 0<age<120:
                self._age=age
            else:
                print("请注意你的年龄范围")
        else:
            print("请输入合法的年龄")
    def get_age(self):
        return self._age


stu=Student("Lady")
stu.set_age(1110)    #输入不规范的年龄
stu.set_age(10)      #设置age,并通过一系列的校验
print(stu.get_age())  #获取age

这样就可以了了 。
2.应用@property 可以把调用的方法像调用属性一样直接用。

Python内置的@property装饰器就是负责把一个方法变成属性调用的:

class Student:
    def __init__(self,name):
        self.name=name

    @property
    def age(self):
        return self._age
    @age.setter
    def age(self,age):
        if isinstance(age,int):
            if 0<age<120:
                self._age=age
            else:
                print("请注意你的年龄范围")
        else:
            print("请输入合法的年龄")



stu=Student("Lady")

stu.age=10   #设置age,并通过一系列的校验
print(stu.age)  #获取age

上边主要以下几点:
1.get 和set 的方法名称都要一样(age)
2.set方法返回的属性要在前面加个"_"
3.@property 是针对get方法
[email protected] 是针对set 方法,是@property本身又创建了另一个装饰器
5.直接可以这样stu.age=10 对象名.方法名进行赋值,
6.只定义getter方法,不定义setter方法是一个只读属性
下边介绍这个特性。

3.只定义getter方法,不定义setter方法就是一个只读属性

class Student:
    def __init__(self,name):
        self.name=name

    @property
    def age(self):
        return self._age
    @age.setter
    def age(self,age):
        if isinstance(age,int):
            if 0<age<120:
                self._age=age
            else:
                print("请注意你的年龄范围")
        else:
            print("请输入合法的年龄")
    @property
    def after_3(self):
        return self._age+3


stu=Student("Lady")

stu.age=10   #设置age,并通过一系列的校验
print(stu.age)  #获取age
stu.after_3=5

打印结果:

AttributeError: can't set attribute

但是我们可以读取 :

print(stu.after_3)

打印结果:

13

猜你喜欢

转载自blog.csdn.net/qq_34979346/article/details/83718252