__slots__ 限制 实例添加额外属性
了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__
变量,来限制该class实例能添加的属性:
class Student(object): __slots__ = ('name','age') # 用tuple定义允许绑定的函数名字
使用 __slots__ 要注意 __slots__ 定义的属性 仅对 当前类实例起作用 对 继承的子类不起作用
class GraduateStudent(Student): pass g = GraduateStudent() g.score = 9999 # 继承的子类可以 实现修改 #除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
@property
Python内置的@property
装饰器就是负责把一个方法变成属性调用
class Room: def __init__(self,name,width,length): self.name=name self.width=width self.length=length @property def area(self): return self.width * self.length r1=Room('alex',1,1) print(r1.area)
定制类
Python 的 class有很多 特殊用的后汉书来帮我们定制类
__str__ __repr__
# 定义一个Student类 打印一个实例 class Student(object): def __init__(self, name): self.name = name print(Student('Micheal'))
<__main__.Student object at 0x00000000028D1128> #__str__ 方法就是为了让这一行更加清晰
常用 __str__ __repr__用法是 组合起来用
class Student(object): def __init__(self, name): self.name = name def __str__(self): return 'Student object (name=%s)' % self.name __repr__ = __str__
''' str函数或者print函数--->obj.__str__() repr或者交互式解释器--->obj.__repr__() 如果__str__没有被定义,那么就会使用__repr__来代替输出 注意:这俩方法的返回值必须是字符串,否则抛出异常 '''
Python式的 getter setter也是用 property实现的
class Foo: @property: def AAA(self): print('get用这个') @AAA.setter def AAA(self,value): print('set 用这个') #只有在属性AAA定义property后才能定义AAA.setter f1 = Foo() f1.AAA # 调用get f1.AAA='AAAasd1' #调用 set
另一种实现形式 是 __getattr__ __setattr__()
class Foo: x=1 def __init__(self,y): self.y=y def __getattr__(self, item): print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value): print('----> from setattr') # self.key=value #这就无限递归了,你好好想想 # self.__dict__[key]=value #应该使用它 #__setattr__添加/修改属性会触发它的执行 f1=Foo(10) print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值 f1.z=3 print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发 f1.xxxxxx
__call__ 当我们调用实例方法时 或许会 使用 isinstance(obj)调用 也可以 使用 __call__方式 使用
枚举类的用法
from enum import Enum class Gender(Enum): Male = 0 Female = 1 class Student(object): def __init__(self, name, gender): self.name = name self.gender = gender bart = Student('Bart', Gender.Male)
元类 的 内容暂时理解很模糊 通读了一遍 廖雪峰老师的 元类介绍