python中的property用法

  • Post author:
  • Post category:python


property用法的用法主要有两点:

一、将方法当做属性来使用

二、将属性设置为只读

下面的例子,给Student类设置了三个私有属性,我们以其中一个属性__score为例,在访问__score时,先要set,然后get才能使用这个属性。如果类似的属性较多,我们就要写很多这样的方法,而且如果需要调用的地方较多,当有很多这些方法的时候,后期维护也很麻烦,先看下面的例子:

class Student:
    __slots__ = ('__name', '__age', '__score')

    def __init__(self, name, age, score=0):
        self.__name = name
        self.__age = age
        self.__score = score

    def getscore(self):
        # print(self.__score)
        return self.__score

    def setscore(self, score):
        if not isinstance(score, int):
            raise ValueError('Score必须是int类型!')
        if score < 0 or score > 100:
            raise ValueError('Score值必须在0=<score<=100')
        self.__score = score


stu = Student("wuli", 28)
stu.setscore(88)
print(stu.getscore())
输出结果:
88

为了解决上面提到的问题,我们可以使用property装饰器,这样就可以把property修饰的方法当做属性来使用,需要的时候直接赋值就可以了,同时,还可以通过这种方法对用户输入的数据做相应的校验。看下面的例子:

class Student(object):
    __slots__ = ('__name', '__age', '__score')

    def __init__(self, name, age, score=0):
        self.__name = name
        self.__age = age
        self.__score = score

    @property
    def score(self):
        return self.__score

    @score.setter
    def score(self, score):
        if not isinstance(score, int):
            raise ValueError('Score必须是int类型!')
        if score < 0 or score > 100:
            raise ValueError('Score值必须在0=<score<=100')
        self.__score = score

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

    @name.setter
    def name(self, name):
        if not isinstance(name, str):
            raise ValueError('name必须是str类型!')
        self.__name = name

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if not isinstance(age, int):
            raise ValueError('Score必须是int类型!')
        self.__age = age
     
stu = Student("化学", 28)
stu.score = 88
print(stu.score)
print(stu.name)
stu.name = "政治"
print(stu.name)
stu.score = 12
print(stu.score)

输出结果:
88
化学
政治
12


注意事项:

1、属性名与方法名一定要区分开,不然会进入死循环(self._age,def age())

2、实例化的对象使用属性时,不是调用属性(stu._age),而是用的方法名(stu.age)

3、@property其实就是实现了getter功能; @xxx.setter实现的是setter功能;还有一个 @xxx.deleter实现删除功能

4、定义方法的时候 @property必须在 @xxx.setter之前,且二者修饰的方法名相同(age())

5、如果只实现了 @property(而没有实现@xxx.setter),那么该属性为 只读属性

二、用property修饰方法后,可以做到变量变为只读,只能在初始化的时候赋值,其他地方不能赋值,只能调用读取其值。

代码示例:

以属性__age为例来演示

class Student:
    __slots__ = ('__name', '__age', '__score')

    def __init__(self, name, age, score=0):
        self.__name = name
        self.__age = age
        self.__score = score

    def getscore(self):
        # print(self.__score)
        return self.__score

    def setscore(self, score):
        if not isinstance(score, int):
            raise ValueError('Score必须是int类型!')
        if score < 0 or score > 100:
            raise ValueError('Score值必须在0=<score<=100')
        self.__score = score

    @property
    def age(self):
        return self.__age

stu = Student("wuli", 110)
print(stu.age)

输出结果:
110

在上面的示例中,我们只能读取在初始化的时候给age的赋值(110),不能对其直接赋值,不然会报错。还是以上面的代码为例:

stu.age = 90
print(stu.age)

输出结果:
  File "xxx/prop.py", line 43, in <module>
    stu.age = 90
AttributeError: can't set attribute


以上仅为学习记录使用,如有侵权,告知删除。



版权声明:本文为m0_57133702原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。