从零开始学Python-Day43-面向对象高级编程-使用__slots__

当我们定义了类class并创建它的实例之后,我们可以给这个实例绑定任何属性和方法,这就是动态语言的灵活性。

我们定义一个class:

<code>

class

Student

(object)

:

pass

/<code>

给创建的实例绑定属性:

<code> > s = Student()
 > s.name = 

'Woodman'

> print(s.name) Woodman/<code>

也可以给实例绑定方法:

<code> > 

def

set_age

(

self

, age): self.age = age > from types import MethodType > s.set_age = MethodType(set_age, s) > s.set_age(

35

) > s.age

35

/<code>

需要注意的是,给一个实例绑定的属性和方法对同一个类的其他实例是不起作用的,这个其实也很好理解,如果要给所有实例都绑定属性或方法就需要对class类去绑定。

<code> > s2 = Student()
 > s2.set_age( 

33

) Traceback (most recent call last): File

""

, line

1

,

in

<

module

> s2.set_age(

33

)

AttributeError:

'Student'

object has no attribute

'set_age'

/<code>

给class绑定属性和方法后,其他实例均可调用:

<code> > 

def

set_score

(

self

, score): self.score = score > Student.set_score = set_score > s.set_score(

100

) > s.score

100

> s2.set_score(

60

) > s2.score

60

/<code>

上面的set_score方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。

__slots__

但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

<code> > 

class

Student

(

object

): __slots_

_

= (

'name'

,

'age'

) > s = Student() > s.name =

'Woodman'

> s.age =

35

> s.score =

100

Traceback (most recent call last): File

""

, line

1

,

in

<

module

> s.score =

100

AttributeError:

'Student'

object has no attribute

'score'

/<code>

可以看到,由于做了slots限制,score这一属性添加不上去,使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类不起作用:

<code> > 

class

GraduatStudent

(

Student

): pass > g = GraduatStudent() > g.score =

100

/<code>

除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。


分享到:


相關文章: