在前边文章介绍过通过实例为类动态添加方法,但是有个问题,添加的方法只是当前实例可用:
def son(self):
print(self.name) # 'lxc'
class Cat:
def __init__(self,name):
self.name = name
c = Cat('lxc')
c1 = Cat('hehe')
c.son_fun = son
c.son_fun(c)
c1.son_fun(c) #AttributeError: 'Cat' object has no attribute
上边代码,通过实例对象c动态添加son方法,但是实例c1缺没有这个方法,通过实例为类添加方法,这种方法很局限!!!我们可以通过类添加,可实现所有实例对象都可以用添加的方法。
通过类添加方法:
def son(self):
print(self.name) # 'lxc'
class Cat:
def __init__(self,name):
self.name = name
c = Cat('lxc')
c1 = Cat('鸡小西')
Cat.son_fun = son
c.son_fun() # 'lxc'
c1.son_fun() # '鸡小西'
上边代码,我们通过类添加了son_fun方法,所有实例都可调用此方法,而且不需要传实例对象,因为python会自动为self绑定实例对象。
上边有个问题,后边程序可以更改添加的方法,如果我们以后不想让后边的程序更改类中的变量和方法,则可以通过__slots__属性来指定。
_ _slots_ _
__slots__属性的值是一个元祖,该元素的所有属性列出了 该 类 的实例 允许 动态 添加的 所有属性名 和 方法名(方法就是属性值为函数的属性)
def son(self):
print(self.name) # 'lxc'
class Cat:
__slots__ = ('name','son_fun')
def __init__(self,name):
self.name = name
c = Cat('lxc')
c.son_fun = son
c.son_fun(c)
c.age = 20 # AttributeError: 'Cat' object has no attribute 'age'
上边代码,__slots__里边定义了' name ' ' son_fun ' 两个属性,程序只允许这两个属性被添加,我们在下边为实例添加age属性,会报错!!!
几个注意点:
1、__slots__并不会阻止通过类添加属性或者方法:
def son(self):
print(self.name) # 'lxc'
print(Cat.age) # 20
class Cat:
__slots__ = ('name','son_fun')
def __init__(self,name):
self.name = name
c = Cat('lxc')
Cat.age = 20
Cat.son_fun = son
c.son_fun()
上边代码,我们通过类添加了一个类变量age,是合法的!(当然通过类添加方法同理,这里不举例了)
2、__slots__只针对当前类起作用,它的子类不起作用,除非自类也定义__slots__。
关于__slots_就这么多,有遗漏地方会及时补充上。。。