类型检测
isinstance(obj,cls)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象
class Foo(object):passobj = Foo()print(isinstance(obj, Foo)) # Truea = 'hello'print(isinstance(a, str)) # Trueb= ['hello']print(isinstance(b, list)) # Truec= ('hello') # str类型c= ('hello', ) # 注意,元素只有一个元素,必须加逗号,否则是这个元素的类型print(isinstance(c, tuple)) # True
issubclass(sub,super)
检查sub类是否是 super 类的派生类
class A:passclass B(A):passclass C(B):passprint(issubclass(B, A)) # trueprint(issubclass(C, A)) # true
item系列
# item系列class Foo(object): # Dictdef __init__(self, name):self.name = namedef __getitem__(self, item): # item='namexxx'# print('getitem...')return self.__dict__.get(item)def __setitem__(self, key, value):# print('setitem...')# print(key,value)self.__dict__[key] = valuedef __delitem__(self, key):# print('delitem...')# print(key)del self.__dict__[key]obj = Foo('ecithy')print(obj.__dict__)# 查看属性:# obj.属性名print(obj['namexxx']) #obj.name# 设置属性:obj.sex='male'obj['sex']='male'print(obj.__dict__)print(obj.sex)# 删除属性del obj.name# del obj['name']print(obj.__dict__)
字符串系列
改变对象的字符串显示__str__ 、__repr__
class School:def __init__(self, name, addr, type):self.name = nameself.addr = addrself.type = typedef __repr__(self):return 'School(%s,%s)' % (self.name, self.addr)def __str__(self):return '(%s,%s)' % (self.name, self.addr)s1 = School('mufeng', '北京', '私立')print('from repr: ', repr(s1))print('from str: ', str(s1))print(repr(s1))print(s1)'''str函数或者print函数--->obj.__str__()repr或者交互式解释器--->obj.__repr__()如果__str__没有被定义,那么就会使用__repr__来代替输出注意:这俩方法的返回值必须是字符串,否则抛出异常'''
对象调用
__call__
对象后面加括号,触发执行。
class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')obj = Foo() # 执行 __init__obj() # 执行 __call__
垃圾回收
__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义del,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了del。
class Foo:def __del__(self):'对象执行结束后一会执行'print('执行我啦')f1 = Foo()del f1 # 立刻执行print('------->')
典型的应用场景:
创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中 当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制del,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源
这与文件处理是一个道理
f=open('a.txt') #做了两件事,在用户空间拿到一个f变量,在操作系统内核空间打开一个文件del f #只回收用户空间的f,操作系统的文件还处于打开状态#所以我们应该在del f之前保证f.close()执行,即便是没有del,程序执行完毕也会自动del清理资源,于是文件操作的正确用法应该是f=open('a.txt')读写...f.close()很多情况下大家都容易忽略f.close,这就用到了with上下文管理
上下文管理
__enter__、__exit__
即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明enter和exit方法
作用:
- 使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
 在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在exit中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处 ```python 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)
__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行```pythonclass Open:def __init__(self,name):self.name=namedef __enter__(self):print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')def __exit__(self, exc_type, exc_val, exc_tb):print('with中代码块执行完毕时执行我啊')print(exc_type)print(exc_val)print(exc_tb)return Truewith Open('a.txt') as f:print('=====>执行代码块')raise AttributeError('***着火啦,救火啊***')print('0'*10) #------------------------------->会执行
迭代器协议
把类变成迭代器
迭代器类型的定义:
- 1.当类中定义了 iter 和 next 两个方法。
 - 2.iter 方法需要返回对象本身,即:self
 - 3. next 方法,返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常。
 
官方文档:https://docs.python.org/3/library/stdtypes.html#iterator-types
# 创建 迭代器类型 :class IT(object):def __init__(self):self.counter = 0def __iter__(self):return selfdef __next__(self):self.counter += 1if self.counter == 3:raise StopIteration()return self.counter# 根据类实例化创建一个迭代器对象:obj1 = IT()# v1 = obj1.__next__()# v2 = obj1.__next__()# v3 = obj1.__next__() # 抛出异常v1 = next(obj1) # obj1.__next__()print(v1)v2 = next(obj1)print(v2)v3 = next(obj1)print(v3)obj2 = IT()for item in obj2: # 首先会执行迭代器对象的__iter__方法并获取返回值,一直去反复的执行 next(对象)print(item)迭代器对象支持通过next取值,如果取值结束则自动抛出StopIteration。for循环内部在循环时,先执行__iter__方法,获取一个迭代器对象,然后不断执行的next取值(有异常StopIteration则终止循环)。
from collections import Iterable,Iteratorclass Range:def __init__(self,n,stop,step=1):self.n=nself.stop=stopself.step=stepdef __next__(self):if self.n >= self.stop:raise StopIterationx=self.nself.n+=self.stepreturn xdef __iter__(self):return selfprint(isinstance(Range(1,7,2), Iterator)) # Truefor i in Range(1,7,2):print(i)# 输出 1 3 5
生成器
把函数变成迭代器
# 创建生成器函数def func():yield 1yield 2# 创建生成器对象(内部是根据生成器类generator创建的对象),生成器类的内部也声明了:__iter__、__next__ 方法。obj1 = func()v1 = next(obj1)print(v1)v2 = next(obj1)print(v2)v3 = next(obj1)print(v3)obj2 = func()for item in obj2:print(item)如果按照迭代器的规定来看,其实生成器类也是一种特殊的迭代器类(生成器也是一个中特殊的迭代器)。
可迭代对象
如果一个类中有iter方法且返回一个迭代器对象 ;则我们称以这个类创建的对象为可迭代对象。
class Foo(object):def __iter__(self):return 迭代器对象(生成器对象)obj = Foo() # obj是 可迭代对象。# 可迭代对象是可以使用for来进行循环,在循环的内部其实是先执行 __iter__ 方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。for item in obj:pass
类的描述信息
__doc__
Python中一切皆对象,函数的基类也是object
def test():'我是函数描述信息'passclass Foo:'我是类描述信息'passprint(Foo.__doc__) # 我是类描述信息print(test.__doc__) # 我是函数描述信息
