property在Python中的作用其实很简单,就是为了简化我们的代码,下面来简单看一个例子:

class Person(object):
    def __init__(self, name, score):
        self.__score = score
        self.name = name

    def getScore(self):
        return self.__score

    def setScore(self,score):
        if score>100 or score<0:
            print("请输入分数在0-100之间!")
        else:
            self.__score = score

    def delScore(self):
        del self.__score

a = Person("张三", 60)
print("{}的得分:{}".format(a.name,a.getScore()))
a.setScore(99)
print("{}的得分:{}".format(a.name,a.getScore()))
a.delScore()
print("{}的得分:{}".format(a.name,a.getScore()))

运行结果:

张三的得分:60
Traceback (most recent call last):
张三的得分:99
  File "D:/自动化B/python_test/test_10_11.py", line 25, in <module>
    print("{}的得分:{}".format(a.name,a.getScore()))
  File "D:/自动化B/python_test/test_10_11.py", line 8, in getScore
    return self.__score
AttributeError: 'Person' object has no attribute '_Person__score'

上面由于对象的属性是私有的,外部是不能直接访问的,所以通过调用对象的方法进行间接的访问,但是你想想有没有感觉不是很简洁,要是有下面这样的代码去访问是不是就很赞:

a.score = 100
print(a.score)
del a.score

那么,你想到的别人早就想到了,那就是使用property就可以实现直接使用对象名.属性名来访问操作对象的内部私有属性。

那么如何使用property来实现上面的简洁使用呢,有两种使用语法:

第一种直接用装饰器的方式:

①在需要简化的属性的get方法头上加上@property;
②修改方法名get ,set,del,使他们的方法名相同;
③在set方法名上加上@方法名.setter
④在del方法名上加上@方法名.deleter
以上设置完之后就大功告成了,后面你就随便使用吧。

class Person(object):
    def __init__(self, name, score):
        self.__score = score
        self.name = name
    @property
    def Score(self):
        return self.__score

    @Score.setter
    def Score(self,score):
        if score>100 or score<0:
            print("请输入分数在0-100之间!")
        else:
            self.__score = score

    @Score.deleter
    def Score(self):
        del self.__score

a = Person("张三", 60)
print("{}的得分:{}".format(a.name,a.Score))
a.Score = 99
print("{}的得分:{}".format(a.name,a.Score))
del a.Score
print("{}的得分:{}".format(a.name,a.Score))

运行结果:

张三的得分:60
Traceback (most recent call last):
张三的得分:99
  File "D:/自动化B/python_test/test_10_11.py", line 27, in <module>
    print("{}的得分:{}".format(a.name,a.Score))
  File "D:/自动化B/python_test/test_10_11.py", line 8, in Score
    return self.__score
AttributeError: 'Person' object has no attribute '_Person__score'

第二种 类属性定义的方式

就是以类属性定义的方式来实例化一个property对象,有的教程里说property是一个函数,我看了Python3.7的源码,property是一个类,类(),我理解的是实例化的过程:
property()有四个参数
第一个参数是方法名,调用 对象.属性时会去自动触发执行该方法
第二个参数是方法名,调用 对象.属性 = XXX 时会去自动触发执行该方法
第三个参数是方法名,调用 del 对象.属性时会去自动触发执行该方法
第四个参数是字符串,调用 对象.属性.doc ,此参数是该属性的描述信息

class Person(object):
    def __init__(self, name, score):
        self.__score = score
        self.name = name

    def getScore(self):
        return self.__score

    def setScore(self,score):
        if score>100 or score<0:
            print("请输入分数在0-100之间!")
        else:
            self.__score = score

    def delScore(self):
        del self.__score

    Score = property(getScore, setScore, delScore,"这是property用来简化score的property定义") 


a = Person("张三", 60)
print("{}的得分:{}".format(a.name,a.Score))
a.Score = 99
print("{}的得分:{}".format(a.name,a.Score))
del a.Score
print("{}的得分:{}".format(a.name,a.Score))

运行结果:

Traceback (most recent call last):
张三的得分:60
  File "D:/自动化B/python_test/test_10_11.py", line 27, in <module>
张三的得分:99
    print("{}的得分:{}".format(a.name,a.Score))
  File "D:/自动化B/python_test/test_10_11.py", line 8, in getScore
    return self.__score
AttributeError: 'Person' object has no attribute '_Person__score'

可以看到和上面的结果是一样的。这里不需要去动对象的方法,直接把对象的方法名扔在property的括号中就可以了。

上面需要注意的是:
property中四个参数的位置不能随便放,第一个必须放置get方法,第二个必须是set方法,第三个必须是del方法,后面的文档说明可以不用写。如果只写1个参数、2个参数、3个参数也是可以的。