Python中@property装饰器的作用

@property的作用:
广泛用于类的定义中,把方法变成属性,保证对参数进行必要的检查,减少程序运行时出错的可能性。

例子:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self.age = age
        self.jobb = job


if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    # 设置妹子的属性
    meizi.gender = "female"
    meizi.age = 18
    meizi.job = "teacher"

    # 访问妹子的属性
    print("妹子信息:")
    print("性别:{gender}".format(gender=meizi.gender))
    print("年龄:{age}".format(age=meizi.age))
    print("职业:{job}".format(job=meizi.job))

# 输出:
#妹子信息:
#性别:female
#年龄:18
#职业:teacher

但是不对,因为如上我们定义的Stranger类,实例化出来的对象meizi还可以这样用:

# ...
if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    # 设置妹子的属性
    meizi.gender = "beijing"
    meizi.age = "teacher"
    meizi.job = 20

    # 访问妹子的属性
    print("妹子信息:")
    print("性别:{gender}".format(gender=meizi.gender))
    print("年龄:{age}".format(age=meizi.age))
    print("职业:{job}".format(job=meizi.job))

# 输出:
#妹子信息:
#性别:beijing
#年龄:teacher
#职业:20

对属性赋值进行约束
这是因为我们没有对属性gender,age,job加以限制,所以可以被用户任意赋值。要约束自然不难,这里单拿属性age作说明:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self.age = age
        self.jobb = job
        
    # 设置age
    def set_age(self, age):
        if isinstance(age, int):
            self.age = age
        else:
        	raise ValueError("'int' type need")
    # 读取age
    def get_age(self):
        return self.age

if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    meizi.set_age(18)
    print("年龄:{age}".format(age=meizi.get_age()))

# 输出:
#年龄:18

如果此时我们做这样的操作:

    meizi.set_age("teacher")
    print("年龄:{age}".format(age=meizi.get_age()))

程序会抛异常ValueError: ‘int’ type need

我们的确实现了预期的目的,但是设置age需要执行meizi.set_age(“teacher”),访问age需要meizi.get_age(),是不是变麻烦呢?

@property的使用

为了避免麻烦,于是有了@property装饰器。它的作用是:将方法变成属性调用。使用示例如下:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self._age = age # 这里的成员属性_age需要与成员方法age()区分开
        self.jobb = job
    # 读取age
    @property # 实现一个age相关的getter方法
    def age(self):
        return self._age
    # 设置age
    @age.setter # 实现一个age相关的setter方法
    def age(self, value):
        if isinstance(value, int):
            self._age = value
        else:
            raise ValueError("'int' type need")

if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    meizi.age = 18  # 使用时注意是.age,不是._age
    print("年龄:{age}".format(age=meizi.age))

# 输出:
#年龄:18

注意事项:

属性名与方法名一定要区分开,不然会进入死循环(self._age,def age())
实例化的对象使用属性时,不是调用属性(meizi._age),而是用的方法名(meizi.age)
@property其实就是实现了getter功能; @xxx.setter实现的是setter功能;还有一个 @xxx.deleter实现删除功能
定义方法的时候 @property必须在 @xxx.setter之前,且二者修饰的方法名相同(age())
如果只实现了 @property(而没有实现@xxx.setter),那么该属性为 只读属性

@property原理

函数接口:property(fget=None, fset=None, fdel=None, doc=None)

使用:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self._age = age
        self.jobb = job

    # 设置_age
    def set_age(self, age):
        if isinstance(age, int):
            self._age = age
        else:
            raise ValueError("'int' type need")

    # 读取_age
    def get_age(self):
        return self._age
	
    # 使得实例化对象可以利用.age方式来访问
    age = property(get_age, set_age)


if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    meizi.age = 18
    print("年龄:{age}".format(age=meizi.age))

# 输出:
#年龄:18
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西门一刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值