[00806]创建可管理的属性

创建可管理的属性

一、 解决问题

给某个实例attribute增加除访问与修改之外的其他处理逻辑,比如类型检查或合法性验证。

二、解决方案

property(把类中定义的函数当做一种属性来处理)

三、代码说明

#/usr/bin/env python

class Person:
    def __init__(self, first_name):
        self.first_name = first_name

    #getter function
    @property
    def first_name(self):
        return self._first_name

    # setter function
    @first_name.setter
    def first_name(self, value):
        if not isinstance(value, str):
            raise TypeError('Excepted a string')
        self._first_name = value

    # delete function
    @first_name.deleter
    def first_name(self):
        raise AttributeError("Can't dlte attribute")

"""
除非属性通过@property的方式定义过了
否则不能定义@属性.setter和@属性.deleter
"""

a = Person("Guido")
print (a.first_name) # call ther getter
#a.first_name = 2 #->Excepted a string
a.first_name = "zhang"
print (a.first_name)

#del a.first_name #->Can't dlte attribute

"""
    当实现一个property时,
    底层的属性(如果有的话)仍然需要被保存到某个地方,
    因此get和set方法中,我们是直接对_first_name进行操作的,则就是属性实际保存的地方。
    在__init()中设置self.first_name是因为,在初始化的时候也会进行类型检查(调用setter方法)

"""
"""
在已经存在的get和set方法中定义property
"""
class Person:
    def __init__(self, first_name):
        self.set_first_name(first_name)

    def get_first_name(self):
        return self._first_name

    def set_first_name(self, value):
        if not isinstance(value, str):
            raise TypeError("excepted a string")
        self._first_name = value


    def del_first_name(self):
        raise AttributeError("Can't delete attribute")

    name = property(get_first_name, set_first_name, del_first_name)

"""
property 实际上就是把一系列方法绑定在一起。
property 底层绑定的方法
"""
print (Person.name.fget)
print (Person.name.fset)
print (Person.name.fdel)

"""
import math
class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def area(self):
        return math.pi * self.radius ** 2

    @property
    def diameter(self):
        return self.radius ** 2

    @property
    def perimeter(self):
        return 2 * math.pi * self.radius

c = Circle(4.0)
print (c.radius)
print (c.perimeter)
#c.perimeter = 2 # 没有setter

四、关联知识

五、总结

(1)如果只是单纯的提供getter/setter的话,不用使用property属性
(2)property可以使得接口便的非常统一 如:Circle类
(3)不用重复性的property的代码。

六、代码地址

github地址:https://github.com/weichen666/python_cookbooka>
目录/文件:eight_selection/learn_class_obj_property.py

七、参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值