模块路径搜索
- 搜索路径
通过sys.path可以查找到模块搜索路径时依赖的路径
- 打包
需要打包时可以上网查找
装饰器
-
高阶函数
import time def deco(func): startTime = time.time() func() endTime = time.time() msecs = (endTime-startTime)*100 print("time is %d ms"%msecs) def func(): print("Hello!") time.sleep() print("World!")
-
简单装饰器
import time def deco(func): def wrapper(): startTime = time.time() func() endTime = time.time() msecs = (endTime-startTime)*100 print("time is %d ms"%msecs) return wrapper @deco def func(): print("Hello") time.sleep(1) print("World") #调用 fun(3,4)
其相当于调用了deco(func)()
其中fun->deco(func) -
对带参数的函数进行装饰
def deco(func): def wrapper(*args,**kwargs): startTime = time.time() func(*args,**kwargs) endTime = time.time() msecs = (endTime-startTime)*1000 print("time is %d ms"%msecs) return wrapper @deco def func(a,b): print("hello") time.sleep() print("world") #调用 fun(3,4)
其相当于调用deco(fun)(3,4)
其中fun->deco(fun) -
带参数的装饰器
def deco(*args,**kargs): def wrapper(func): def inner(): startTime = time.time() func() endTime = time.time() msecs = (endTime-startTime)*1000 print("time is %d ms"%msecs) return inner @deco("王") def func(): print("hello") #调用 func()
其相当于调用 deco(“王”)(func)()
其中fun->deco(“wang”)(func)
注:其调用原理都相同可以自行解决
闭包
-
闭包的定义
扫描二维码关注公众号,回复: 5514466 查看本文章闭包是由函数及其相关的引用环境组合而成的实体
-
闭包的条件
-
外部函数返回内部函数的引用
-
内部函数使用外部变量
`def outer(): m=1 def inner(): n=10 s=m+n return inner
当outer将会把inner与引用环境打包成一个整体(整体)反回
d =outer() d.__closure__[0].cell_contents
可以说闭包是通过__closure__实现的
对象继承问题
-
dir() 与__dict__区别
dir()是python提供的一个API函数,该函数会自动寻找一个对象的所有属性。包括类属性、实例属性、方法等
__dict__是存储实例属性的一个字典,即存储实例独有的属性class Student: m=1 def __init__(self): self.age=10 class Teacher(Student): def __init__(self): Student.__init__(self) self.name="wang" >>> t= Teacher() #两者的区别 >>> t.__dict__ {'age': 10, 'name': 'wang'} >>>dir(t) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'm', 'name']
这种区别可以让人理解继承的含义
-
调用父类的构造方法
-
经典写法
父类名称.init(self,参数1,参数2…)
即使用非绑定的类方法(用类名来引用的方法),并在参数列表中引入待绑定的对象,从而达到调用父类的目的 -
新式写法
super(子类,self).init(参数1,参数2…)
-
调用函数或者属性时的顺序问题
Python的多继承类时通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次
可以调用__mro__来查看类的继承关系
对象创建问题
- 类的创建过程
-
call
其用法主要包括如下两种:
1)方法def fun(m): print(m) #正常使用函数 fun(11) #使用call方法调用函数 fun.__call__(11)
2)类
class Student: def __init__(self): self.name = "wang" def __call__(self,*args,**kargs): print("li") #创建对象 s = Student() #间接调用了对象的__call__方法 s() #直接调用对象的__call__方法 s.__call__()
综上当调用XXX()时内部调用的其实时XXX.__call__方法
-
__new__方法
__new__() 方法是在类准备将自身实例化时调用
__new__()方法始终都是类的静态方法,即使没有被加上静态装饰器
类的实例化和它的构造方法通常时这个样子
-
元类(生成类的类)创建类
#参数为 类名 继承的父类 属性名 Studnet = type('Student',(object,),{'x':1})
-
自定义类
#元类定义 class MyType(type): def __init__(self,*args,**kargs): print("元类") def __call__(self, *args, **kwargs): obj = self.__new__(self,*args,**kwargs) self.__init__(obj,*args,**kwargs) return obj #指定元类 class Foo(metaclass = MyType):#相当于 Foo = MyType('Foo',(),{}) def __init__(self,name): self.name = name def __new__(cls, *args, **kwargs): print(cls) print("__new__") return object.__new__(cls) #使用类 f= Foo('wang') print(f.name)
描述符
-
描述符
描述符本支是一个新式类,至少实现了__get__,set,__delete__中的一个,这也称为描述符协议
-
描述符的作用
描述符的作用是用来代理另外一个类的类属性的。必须把描述符定义为一个类的属性,不能定义在构造函数中
-
分类
-
数据描述符
至少实现了get与set方法的描述符
-
非数据描述符
没有set方法的描述符
- 查找顺序
查找b.x属性的过程1、查找属性的第一步时搜索积累列表,即type(b).mro(),直到找到该属性的第一个定义,并将值赋值给descr
2、判断descr类型。它的类型分为数据描述符、非数据描述符、普通属性、未找到类型。若descr为数据描述符,则调用descr.get(b,type(b))
3、如果descr为非数据描述符、普通属性、未找到等数据,则查找实例b的实例属性,即在b.__dict__中查找。如果找到则将结果返回,结束执行。否则进行下一步
4、如果在b.__dict__未找到相关属性,则重新回到descr值的判断上
1)若descr为非数据描述符,则调用descr.get(b,type(b)),并将数据返回
2)若descr为普通属性,直接返回结果并结束执行
3)若descr为空(未找到),则最终抛出AttributeError异常,结束查找
魔法方法
-
getattr
当用户试图获取一个不存在的属性时的行为
-
getattribute
定义该类的属性被访问时的行为,返回对象时需要使用父类的__getattribute__方法
class Foo(): def __init__(self,name): self.name = name def __getattribute__(self, item): print(item) return object.__getattribute__(self,item)#重点 def __getattr__(self, item): print(item) #调用 f= Foo('wang') print(f.name)
-
setattr
当一个属性被设置时的行为,调用时需要通过父类的__setattr__来设置值
class Foo():
def init(self,name):
self.name = namedef __getattribute__(self, item): print(item) return object.__getattribute__(self,item)#重点 def __getattr__(self, item): print(item) def __setattr__(self, key, value): object.__setattr__(self,key,value)#重点 #调用 f= Foo('wang') print(f.name)
-
反射机制
可以使用hasattr 、getattr 、setattr等三个函数来实现反射