目录
__init__,__setattr__,__delattr__,__getattr__
__get__,__set__,__delete__(描述符)
__str__、__repr__、__format__、 __del__、 __call__
__init__,__setattr__,__delattr__,__getattr__
class Foo: x=1 def __init__(self,y): print('__init__在实例化对象时调用') self.y=y def __getattr__(self, item): print('__getattr__只有在使用点调用属性且属性不存在的时候才会触发') def __setattr__(self, key, value): print('__setattr__ 赋值操作(添加/修改属性)会触发它的执行') def __delattr__(self, item): print('__delattr__删除属性的时候会触发') self.__dict__.pop(item) #__setattr__ 赋值操作(添加/修改属性)会触发它的执行 f1=Foo(10) print(f1.__dict__) # 重写了__setattr__,凡是赋值操作都会触发它的运行 f1.z=3 print(f1.__dict__) #__delattr__删除属性的时候会触发 f1.__dict__['a']=3 #直接修改属性字典,来完成添加/修改属性的操作 del f1.a print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发 f1.xxxxxx
__getattr__、__getattribute__
class Foo: def __init__(self,x): self.x=x def __getattr__(self, item): print('__getattr__只有在使用点调用属性且属性不存在的时候才会触发') def __getattribute__(self, item): print('单独存在时,不管是否存在,都会执行') raise AttributeError('__getattribute__异常') f1=Foo(10) f1.x f1.y #当__getattribute__与__getattr__同时存在,只会执行__getattrbute__ #除非__getattribute__在执行过程中抛出异常AttributeError
__get__,__set__,__delete__(描述符)
''' 描述符:本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议 __get__():调用一个属性时,触发 __set__():为一个属性赋值时,触发 __delete__():采用del删除属性时,触发 ''' class Foo: def __get__(self, instance, owner): pass def __set__(self, instance, value): pass def __delete__(self, instance): pass
__str__、__repr__、__format__、 __del__、 __call__
''' __str__ 对象打印时触发,用来自定义打印信息 __repr__对象用于交互式解释器,若str没有被定义,则使用repr来代替输出 注意:上方两个方法,必须返回值为字符串,否则抛出异常 __format__自定制格式化字符串 __del__ 对象被删时触发,内部可以用来回收对象以外的资源,如系统资源 __call__ 对象被调用时触发,用来实现对象的调用 ''' format_dict={ 'nat':'{obj.name}-{obj.addr}-{obj.type}', # 学校名-学校地址-学校类型 'tna':'{obj.type}:{obj.name}:{obj.addr}', # 学校类型:学校名:学校地址 'tan':'{obj.type}/{obj.addr}/{obj.name}', # 学校类型/学校地址/学校名 } class test: def __init__(self, name, age, filepath): self.name = name self.age = age self.f = open(filepath, 'rt', encoding='utf-8') def __str__(self): return '<name:%s,age:%s>' % (self.name, self.age) def __repr__(self): return '<name:%s,age:%s>' % (self.name, self.age) def __format__(self,format_spec): if not format_spec or format_spec not in format_dict: format_spec = 'nat' fmt = format_dict[format_spec] return fmt.format(obj = self) def __del__(self): print('is deleted') # 进行回收对象关联的资源 self.f.close() def __call__(self, *args, **kwargs): print(self, args, kwargs) obj = test('t1', 18, 'D:\python\old_boy2\object_oriented\settings.py') obj(1,2,a=3,b=4) print(obj) del obj
__slots__
''' 1.__slots__:一个类变量;变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性) 2.引子: 使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的) 3.使用__slots__原因: 字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__。 当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。 实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典,这跟元组或列表很类似。 在__slots__中列出的属性名在内部被映射到这个数组的指定小标上。 使用__slots__一个不好的地方就是我们不能再给实例添加新的属性了,只能使用在__slots__中定义的那些属性名。 4.注意事项: __slots__的很多特性都依赖于普通的基于字典的实现。 另外,定义了__slots__后的类不再 支持一些普通类特性了,比如多继承。 大多数情况下,你应该只在那些经常被使用到 的用作数据结构的类上定义__slots__。 比如在程序中需要创建某个类的几百万个实例对象 。 关于__slots__的一个常见误区: 是它可以作为一个封装工具来防止用户给实例增加新的属性。 尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。 更多的是用来作为一个内存优化工具。 ''' class Foo: __slots__='x' f1=Foo() f1.x=1 f1.y=2#报错 print(f1.__slots__) #f1不再有__dict__ class Bar: __slots__=['x','y'] n=Bar() n.x,n.y=1,2 n.z=3#报错
__next__和__iter__实现迭代器协议
class Foo: def __init__(self,x): self.x=x def __iter__(self): return self def __next__(self): n=self.x self.x+=1 return self.x f=Foo(3) for i in f: print(i)
__doc__
__doc__查看对象的注释(‘’‘xxxx’‘’)信息
class Foo: '我是描述信息' pass print(Foo.__doc__)
__module__和__class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
__enter__和__exit__
class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') # return self def __exit__(self, exc_type, exc_val, exc_tb): print('with中代码块执行完毕时执行我啊') with Open('a.txt') as f: print('=====>执行代码块') # print(f,f.name)
类的专有方法
__init__ 构造函数,在生成对象时调用 __del__ 析构函数,释放对象时使用 __repr__ 打印,转换 __setitem__ 按照索引赋值 __getitem__ 按照索引获取值 __len__ 获得长度 __cmp__ 比较运算 __call__ 函数调用 __add__ 加运算 __sub__ 减运算 __mul__ 乘运算 __div__ 除运算 __mod__ 求余运算 __pow__ 乘方