使用_ _slots_ _
# class Student(object):#创建一个类,类中不存放仍何属性 # pass
# s=Student() #调用类 # s.name='Michael'#给类一个属性 # print(s.name)
# def set_age(self,age):#定义一个方法 # self.age=age # s=Student()#调用类 # from types import MethodType #引用模块 # s.set_age=MethodType(set_age,s) #将实例与方法绑定 # s.set_age(33) # 给实例一个值并调用方法 # print(s.age) #注:上面的方法只能作用与s.set_age(33)这个实例其它实例不可调用 # s2=Student() # s2.set_age(15) # print(s2.age) # def set_score(self,score): #定义一个方法 # self.score=score # Student.set_score=set_score #将方法与类绑定 #注:这样任何实例都可以调用此方法 # s=Student() # s.set_score(100) # print(s.score) # s1=Student() # s1.set_score(50) # print(s1.score)
通常情况下,上面的set_score
方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能
_ _slots_ _:限制实例的属性
# class Student(object): # __slots__ = ('name', 'age') #限制类的实例属性,只能添加name与age # s=Student() # s.name='ww' # s.age=25 # # s.score=77 #由于__slots__中没有score属性所有添加s.score实例时会报错 # print(s.name,s.age)
使用__slots__
要注意,__slots__
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。
除非在子类中也定义__slots__
,这样,子类实例允许定义的属性就是自身的__slots__
加上父类的__slots__
。
使用@property
对于类的方法,装饰器一样起作用。Python内置的@property
装饰器就是负责把一个方法变成属性调用的
小结
@property
广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。
多重继承
# class Aa(object):#定义第一个父类 # def run(self): # print('hello') # class Bb(object):#定义第二个父类 # def run(self): # print('whord') # class Cc(Aa,Bb):#将两个父类的方法都加入到子类中 # pass # c=Cc() # c=c.run()#同名方法会使用 第一个父类中的方法 # print(c)
通过多重继承,一个子类就可以同时获得多个父类的所有功能。
主线都是单一继承下来的,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich
除了继承自Bird
外,再同时继承Runnable
。这种设计通常称之为MixIn。
MixIn的目的就是给一个类增加多个功能。
小结
由于Python允许使用多重继承,因此,MixIn就是一种常见的设计。
只允许单一继承的语言(如Java)不能使用MixIn的设计。
定制类
_ _str_ _返回一个好看的字符串
_ _iter_ _ 该方法返回一个迭代对象
_ _getitem_ _像list那样按照下标取出元素
_ _getattr_ _ 当调用一个不存在的属性时,动态返回一个属性
_ _call_ _ 直接对实例进行调用
枚举类
当我们需要定义常量时,一个办法是用大写变量通过整数来定义
好处是简单,缺点是类型是int
,并且仍然是变量。
更好的方法是为这样的枚举类型定义一个class类型,然后,每个常量都是class的一个唯一实例。
# from enum import Enum #引入模块Enum # Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) # for name, member in Month.__members__.items(): # # print(name, '=>', member, ',', member.value)
value
属性则是自动赋给成员的int
常量,默认从1
开始计数。
如果需要更精确地控制枚举类型,可以从Enum
派生出自定义类