@property的使用

@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 来实现,是不是简单很多呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值