python 类中__slots__ 和 @property

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011510825/article/details/80149360
  1. slots 
将字符串属性名称顺序赋值给特殊的__slots__类属性,就可以限制类的实例将有的合法属性集。
这个比较简单,例如:

>>> class people(object):
...     __slots__ = ['age', 'name’]
限制了people只有age和name的属性。

对比下就知道了。
>>> class all(object):
…     pass

>>> a = people()
>>> b = all()
>>>
>>> a.age = 1
>>> a.age
1
>>> b.age = 2
>>> b.age
2
>>>
>>> a.gender = 'male'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'people' object has no attribute 'gender'
>>> b.gender = 'male'
>>> b.gender
'male'
先对age赋值,a,b都正常,在对性别赋值,a直接报错,因为people加了__slots__限制,只能有age和name实例属性。

为啥要用__slots__呢? 性能问题
使用__slots__是有副作用的

1. 每个继承的子类都要重新定义一遍__slots__
2. 实例只能包含哪些在__slots__定义的属性,这对写程序的灵活性有影响,比如你由于某个原因新网给instance设置一个新的属性,比如instance.a = 1, 但是由于a不在__slots__里面就直接报错了,你得不断地去修改__slots__或者用其他方法迂回的解决
所以实例不超过万级别的类,__slots__是不太值得使用的,麻烦啊,还有就是不利于别人阅读你的代码,并不一定pythoner都知道这个属性啊,还得害人家google了解一下。
PS:《fluent python》比我狠,说的是小于百万级别实例不值得使用。


2.property 

在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:

class Student (object):
    pass

s = Student()
s.score = -1

这其实很不合理,我们需要对score参数做检查,
class Student (object):

    def get_score(self):
        return self._score

    def set_score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

现在,对任意的Student实例进行操作,就不能随心所欲地设置score了:
>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999)
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!

但是其实挺麻烦的,python的思想是简单。

Python内置的@property装饰器就是负责把一个方法变成属性调用的

class Student (object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作。

Python内置的@property装饰器就是负责把一个方法变成属性调用的,将属性变成不可更改。


猜你喜欢

转载自blog.csdn.net/u011510825/article/details/80149360