##getattribute isinstance issubclass
class Foo(): def __init__(self,x): self.x = x def __getattr__(self, item): print('执行的是getattr')#当下一个方法抛出异常 接着避免程序崩溃 def __getattribute__(self, item): print('执行的是getattribute') raise AttributeError('抛出异常了') #抛出异常找小弟去了 class Bar(Foo): pass f1 = Foo(10) print(isinstance(f1,Foo)) #判断此实例是否来自此类 print(issubclass(Bar,Foo)) #判断是否为子类 print(f1.xx)
#item是基于字典的方式对数据进行操作
class Foo: def __getitem__(self, item): print('getitem') return self.__dict__.keys() def __setitem__(self, key, value): print('setitem') self.__dict__[key] = value def __delitem__(self, key): print('delitem') self.__dict__.pop(key) f1 = Foo() print(f1.__dict__) f1['name'] = 'egg' f1[1] = '22' print(f1.__dict__) # del f1.name del f1['name'] print(f1.__dict__)
##str & repr
二者皆用于控制输出 但不能输出非字符串类型
class Foo: def __init__(self,name,age): self.name =name self.age = age def __str__(self): print('name is %s age is %s'%(self.name,self.age)) return 'str自定制的对象显示方式' #打印实例时的显示 def __repr__(self): #在解释器中作用 return 'name is %s age is %s' %(self.name,self.age) pass f1 = Foo('alex',18) print(f1) #若找不到str 就找repr做替代品
自定制format
class Date: def __init__(self,year,mon,day): self.year = year self.mon = mon self.day = day d1 = Date(2019,3,1) print(d1.__dict__) x = '{0.year}-{0.mon}-{0.day}'.format(d1) print(x) format_dict = { 'ymd':'{0.year}{0.mon}{0.day}', 'y-m-d':'{0.year}-{0.mon}-{0.day}' } class Date: def __init__(self,year,mon,day): self.year = year self.mon = mon self.day = day def __format__(self, format_spec): print('format is running') if not format_spec or format_spec not in format_dict: format_spec = 'ymd' fm = format_dict[format_spec] return fm.format(self) d1 = Date(2019,3,1) print(format(d1))
slota__是什么 是一个类变量 变量值可以是列表 元组 也可以是可迭代对象
引子:使用点来访问属性本质就是在访问类或者对象的dict属性字典
(类的字典是共享的 而每个实例是独立的)
class Foo: __slots__ = 'name' f1 = Foo() f1.name = 'egg' print(f1.name) # doc class Foo: 'i am distribute' pass class Bar(Foo): pass print(Bar.__doc__) #属性无法继承子类 print(Foo.__doc__) #from lib.aa import C # c1 = C() # print(c1.name) # print(c1.module) #查询来自哪个模块 # print(c1.class) #查询来自哪个类
#析构方法
class Foo: def __init__(self,name): self.name = name def __del__(self): print('i am running') f1 = Foo('alex') del f1 del f1.name print('__________>>>')
# # __call__
# #对象后面加括号 触发执行
class Foo: def __call__(self, *args, **kwargs): print('实例能执行啦 obj()') pass f1 = Foo() f1()
#迭代器协议
class Foo: def __init__(self,n): self.n = n def __iter__(self): return self def __next__(self): if self.n == 13: raise StopIteration('stop!!!!') self.n+=1 return self.n # f1 = Foo(10) # # print(f1.__next__()) # # print(f1.__next__()) # # print(f1.__next__()) # # print(f1.__next__()) # for i in f1: # print(i)
#斐波那契数列
import time class Fib: def __init__(self,a,b): self.a = a self.b = b def __iter__(self): return self def __next__(self): if self.a > 100 or self.b > 100: raise StopIteration('stop!!!!') self.a,self.b = self.b,self.a + self.b return self.a # f1 = Fib(1,1) # print(f1.__next__()) # print(f1.__next__()) # for i in f1: # time.sleep(0.2) # print(i)
# 优先级:类属性 数据描述符 实例属性 非数据描述符
# 找不到的属性触发__getattr__()
引用模块时注意路径:
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) sys.path.append(BASE_DIR)