属性
属性
访问限制
在某些情况下,我们希望限制用户访问对象的属性或方法,也就是希望它是私有的,对外隐蔽。比如,对于上面的例子,我们希望__
,对上面的例子做一点改动:
class Animal(object):
def __init__(self, name):
self.__name = name
def greet(self):
print 'Hello, I am %s.' % self.__name
>>> dog1 = Animal('dog1')
>>> dog1.__name # 访问不了
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-206-7f6730db631e> in <module>()
----> 1 dog1.__name
AttributeError: 'Animal' object has no attribute '__name'
>>> dog1.greet() # 可以访问
Hello, I am dog1.
slots 魔法
在
class Point(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
>>> p = Point(3, 4)
>>> p.z = 5 # 绑定了一个新的属性
>>> p.z
5
>>> p.__dict__
{'x': 3, 'y': 4, 'z': 5}
在上面,我们创建了实例__slots__
来告诉
class Point(object):
__slots__ = ('x', 'y') # 只允许使用 x 和 y
def __init__(self, x=0, y=0):
self.x = x
self.y = y
上面,我们给 __slots__
设置了一个元组,来限制类能添加的属性。现在,如果我们想绑定一个新的属性,比如
>>> p = Point(3, 4)
>>> p.z = 5
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-648-625ed954d865> in <module>()
----> 1 p.z = 5
AttributeError: 'Point' object has no attribute 'z'
使用 __slots__
有一点需要注意的是,__slots__
设置的属性仅对当前类有效,对继承的子类不起效,除非子类也定义了 __slots__
,这样,子类允许定义的属性就是自身的
使用@property
在使用 @property
之前,让我们先来看一个简单的例子:
class Exam(object):
def __init__(self, score):
self._score = score
def get_score(self):
return self._score
def set_score(self, val):
if val < 0:
self._score = 0
elif val > 100:
self._score = 100
else:
self._score = val
>>> e = Exam(60)
>>> e.get_score()
60
>>> e.set_score(70)
>>> e.get_score()
70
在上面,我们定义了一个_score
属性操作,我们提供了property
装饰器,被装饰的方法,我们可以将其『当作』属性来用,看下面的例子:
class Exam(object):
def __init__(self, score):
self._score = score
@property
def score(self):
return self._score
@score.setter
def score(self, val):
if val < 0:
self._score = 0
elif val > 100:
self._score = 100
else:
self._score = val
>>> e = Exam(60)
>>> e.score
60
>>> e.score = 90
>>> e.score
90
>>> e.score = 200
>>> e.score
100
在上面,我们给方法@property
,于是我们可以把score.setter
,它可以把被装饰的方法变成属性来赋值。另外,我们也不一定要使用 score.setter
这个装饰器,这时
class Exam(object):
def __init__(self, score):
self._score = score
@property
def score(self):
return self._score
>>> e = Exam(60)
>>> e.score
60
>>> e.score = 200 # score 是只读属性,不能设置值
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-676-b0515304f6e0> in <module>()
----> 1 e.score = 200
AttributeError: can't set attribute