版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011510825/article/details/80149360
- 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装饰器就是负责把一个方法变成属性调用的,将属性变成不可更改。