@property的使用

    科技2022-08-23  101

    @property最主要的功能就是负责把一个方法变成属性调用。

    那么在实际应用中,我们具体怎么使用呢?

    1. 把一个方法变成属性调用

    有时,我们在定义一个类时,需要设置私有属性,外部可以访问,但是不希望外部对属性进行更改。

    class Person(object): def __init__(self): self._name = "小明" # 但下划线开头表示这是私有属性,但是外部依然可以访问更改 self._age = 18 self._gender = "男" # 查看私有属性 person_1 = Person() print(person_1._name) print(person_1._age) print(person_1._gender) 小明 18 男 # 对私有属性进行修改 person_2 = Person() person_2._name = "小红" print(person_2._name) print(person_2._age) print(person_2._gender) 小红 18 男

    可以通过@property的方法来进行设置。这样可以隐藏属性名,让用户进行使用的时候无法随意修改。

    class Person(object): def __init__(self): self._name = "小明" self._age = 18 self._gender = "男" @property def name(self): return self._name @property def age(self): return self._age @property def gender(self): return self._gender person_1 = Person() # 通过调用方法的方式查看属性,使用者不需要知道属性值,只需要知道该方法 print(person_1.name) # 使用调用属性的方式调用方法,后面不需要加() print(person_1.age) print(person_1.gender) 小明 18 男

    修饰方法,使方法可以像属性一样访问

    class Person(object): def __init__(self): self._name = "小明" def get_age(self): # 调用该方法时需要加() return 18 @property # 可以用调用属性的方法调用该方法,不需要加() def get_gender(self): return "男" person_1 = Person() print(person_1._name) age = person_1.get_age() # 没有@property调用方法需要加() print(age) gender = person_1.get_gender # 有了@property调用方法不需要加() print(gender) 小明 18 男

    此时,我的疑惑是将方法当作属性一样访问能有什么好处呢?看了以下代码就明白了

    class Person(object): def __init__(self,name,age,gender=None): self._name = name self._age = age self._gender = gender person_1 = Person("小明","男性") name = person_1._name age = person_1._age print("{}的年龄是:{}".format(name,age)) 小明的年龄是:男性

    以上的代码在设置年龄时并没有检查年龄的类型,所以"男性"被当作年龄赋值给了age。为了避免这个错误,我们在设置属性值的时候,需要添加一个set方法,用来检查输入的属性值是否正确

    class Person(object): def __init__(self,name=None,age=None,gender=None): self._name = name self._age = age self._gender = gender def set_age(self,age): # 设置年龄属性 if isinstance(age,int): self._age = age else: raise ValueError("请输入int类型") def get_age(self): # 获取年龄 return self._age person_1 = Person("小明") age_set = person_1.set_age("男性") # 输入错误的age类型 name = person_1._name age = person_1.get_age() print("{}的年龄是:{}".format(name,age)) ValueError Traceback (most recent call last) <ipython-input-100-d071f5fc5e66> in <module>() 1 person_1 = Person("小明") ----> 2 age_set = person_1.set_age("男性") 3 name = person_1._name 4 age = person_1.get_age() 5 print("{}的年龄是:{}".format(name,age)) <ipython-input-98-b6d73e549a9e> in set_age(self, age) 10 return self._age 11 else: ---> 12 raise ValueError("请输入int类型") 13 14 def get_age(self): ValueError: 请输入int类型 person_1 = Person("小明") age = person_1.set_age(18) name = person_1._name print("{}的年龄是:{}".format(name,age)) 小明的年龄是:18

    以上的代码虽然正确,但是不是很麻烦,设置年龄需要person_1.set_age(),获取年龄需要 age = person_1.get_age(),如果使用@property方法呢?

    使用@property对以上代码进行修改

    class Person(object): def __init__(self,name=None,age=None,gender=None): self._name = name self._age = age self._gender = gender @property # 读取age,相当于上面的get_age方法 def age(self): return self._age @age.setter # 设置age,相当于上面的set_age方法 def age(self,age): if isinstance(age,int): self._age = age else: raise ValueError("请输入int类型") person_1 = Person("小明") person_1.age = "男性" # 注意虽然用调用属性的方式调用age方法,但是调用的仍是age()方法,不是._age name = person_1._name age = person_1.age print("{}的年龄是:{}".format(name,age)) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-102-c3769d8541af> in <module>() 1 person_1 = Person("小明") ----> 2 person_1.age = "男性" 3 name = person_1._name 4 age = person_1.age 5 print("{}的年龄是:{}".format(name,age)) <ipython-input-101-c21e1cb55869> in age(self, age) 14 self._age = age 15 else: ---> 16 raise ValueError("请输入int类型") ValueError: 请输入int类型 person_1 = Person("小明") person_1.age = 18 age = person_1.age name = person_1._name print("{}的年龄是:{}".format(name,age)) 小明的年龄是:18

    以上我们看出,@property装饰的作用下,设置和获取属性时我们只需要person_1.age 来实现,是不是简单很多呢?

    Processed: 0.008, SQL: 10