__slots__和@property

__slots__,封装属性

__slots__常见的的用法是用来封装属性,限制对实例胡乱添加属性。然而他还有一个重要的作用是可以减少内存使用。
当定义了__slots__属性时,Python就会针对实例采用一种更加紧凑的内部表示。不在让每个实例都创建一个__dict__字典,现在的实例是围绕着一个固定长度的小型数组来构建的,这和一个元组或者列表很相似。在__slots__中列出的属性名会在内部映射到这个数组的特定索引上。使用__slots__所带来的副作用是我们没法在对实例添加任何新的属性了——我们被限制在只允许使用__slots__中列出的那些属性名。

class Date(object):
    __slots__ = ['year', 'month', 'day']

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

d = Date('2017', '11', '21')
print(d.year+'-'+d.month+'-'+d.day)
#输出
2017-11-21

#设置属性hour
d.hour = '19'
#报错
AttributeError: 'Date' object has no attribute 'hour'

@property,创建可管理的属性

在对实例属性的获取和设定上,如果希望能够增加一些额外的处理过程(如类型检查或者验证),一种简单的方式是将其定义为property(也即把类中定义的函数当做一种属性来使用)。

class A(object):

    def __init__(self, name):
        self.name = name

    # 将name定义为property属性,此处增加了增加了对name属性的修饰
    @property
    def name(self):
        return 'my name is: ' + self._name

    # 将可选方法setter绑定到name属性上,设定属性时做类型检查
    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise TypeError('Expect a string')
        self._name = value

    # 将可选方法deleter绑定到name属性上,此处设置为属性不可删除
    @name.deleter
    def name(self):
        raise AttributeError('Cannot delet attribute!')

a = A('a')
a.name = 'shexuan'
print(a.name)
#输出
my name is: shexuan

#设置name属性为int(10)
a.name = 10
#报错
TypeError: Expect a string

你可能感兴趣的:(__slots__和@property)