python之旅5【第五篇】

装饰器详解

函数刚开始不解析内部,只是放进内存

装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作。

1 下面以一个函数开始,理解下面概念

 def  foo():
print 'foo' foo 是函数
foo() 是执行函数

2 看下面的一个函数执行过程

 def  f1(arg):
arg() def func():
print '' f1(func)

python之旅5【第五篇】

3 上面的理解之后,看下面一个函数执行过程

 def auth(func):
def wrapper():
print "before"
func()
return wrapper
def f1():
print "f1"
auth(f1)

python之旅5【第五篇】

4 接着上边的,如何执行内部的内容, 引入装饰器

还是上面的函数,换了执行方式

 def auth(func):
def wrapper():
print "before"
func()
return wrapper
def f1():
print "f1"
ret=auth(f1)
ret()

python之旅5【第五篇】

5 装饰器引入

 def auth(func):
def wrapper():
print "before"
func()
return wrapper @auth
def f1():
print "f1 @auth=>auth(f1)==>f1=auth(f1)=def wrapper():
print "before"
func()
接下来再执行f1()就相当于执行了wrapper()函数
主要过程是执行auth函数,被装饰的函数作为参数传入auth--auth(f1),auth函数的返回值,赋值给被装饰的函数的函数名,---f1=wrapper

6 装饰器含参数(一个参数)

 def auth(func):
def inner(arg):
print "before"
func(arg)
return inner
@auth
def f2(arg):
print "f2" ,arg
f2('test') 结果
before
f2 test

7 多个参数,动态参数

 def auth(func):
def inner(*args,**kwargs):
print "before"
func(*arg,**kwargs)
print 'after'
return inner @auth
def f2(*args,**kwargs):
print "f2" f2('1.1.1.1')

8 含有返回值的装饰器

 def auth1(func):
def inner(*arg,**kwargs):
print 'before'
temp = func(*arg,**kwargs)
print 'after'
return temp #inner函数有了返回值
return inner @auth1
def fetch_list(arg):
print "fetch_list"
server_list = [,,]
return server_list ret = fetch_list('test')
print ret 结果
before
fetch_list
after
[, , ]

9 装饰器实现登录验证

主要就是增加了一个login函数

 def login():
name = 'dicky'
if name == 'dicky1':
return True
else:
return False def auth3(func):
def inner(*args,**kwargs):
is_login = login()
if not is_login:
return "invild"
temp = func(*args,**kwargs)
return temp
return inner
@auth3
def fetch_list(arg):
print "fetch_list"
server_list = [,,]
return server_list
ret=fetch_list('test')
print ret 结果
invild

10 装饰器实现token验证,跟上面的login差不多

 def login1(key):
name = 'alex1'
local = 'afcadfsgdgwegsfbdfgsgsfwe'
if local == key:
return True
else:
return False
def auth3(func):
def inner(*arg,**kwargs):
# key=kwargs['token']
# del kwargs['token']
key = kwargs.pop('token') #删除多传入的参数
is_login = login1(key)
if not is_login:
return "invild"
print 'before'
temp = func(*arg,**kwargs) #上面删除了多传入的参数,这里就不会报错了
print 'after'
return temp
return inner @auth3
def fetch_list(arg):
print "fetch_list"
server_list = [,,]
return server_list key = 'afcadfsgdgwegsfbdfgsgsfwe'
ret = fetch_list('test',token=key)
print "llllllllll"
print ret

11 多装饰器

先执行外部装饰器,然后在执行内部装饰器

 def w1(func):
def inner():
print 'w1 before'
func()
print 'w1 after'
return inner
def w2(func):
def inner():
print 'w2 after'
func()
print 'w2 after'
return inner
@w2
@w1
def foo():
print 'foo' foo()
结果
w2 after
w1 before
foo
w1 after
w2 after

12 装饰器附加参数

 def Before(request,kargs):
print 'before' def After(request,kargs):
print 'after' def Filter(before_func,after_func):
def outer(main_func):
def wrapper(request,kargs): before_result = before_func(request,kargs)
if(before_result != None):
return before_result; main_result = main_func(request,kargs)
if(main_result != None):
return main_result; after_result = after_func(request,kargs)
if(after_result != None):
return after_result; return wrapper
return outer @Filter(Before, After)
def Index(request,kargs):
print 'index'

过程如下

 @Filter(Before, After)

先执行Filter(Before, After)函数,获取返回值ret,获取返回值后,拼接成@ret,也就是相当于引入了两个参数,以至于后来可以使用这两个参数。

13 functools.wraps 的作用

上述的装饰器虽然已经完成了其应有的功能,即:装饰器内的函数代指了原函数,注意其只是代指而非相等,原函数的元信息没有被赋值到装饰器函数内部。例如:函数的注释信息

看下面的两个例子

def outer(func):
def inner(*args, **kwargs):
print(inner.__doc__) # None
return func()
return inner @outer
def function():
"""
asdfasd
:return:
"""
print('func') function()
结果
None #并没有输出__doc__的信息

加上@functools.wraps之后

  import functools
1 def outer(func):
@functools.wraps(func)
def inner(*args, **kwargs):
print(inner.__doc__) # None
return func()
return inner @outer
def function():
"""
asdfasd
:return:
"""
print('func') function()
结果
asdfasd
:return: func #输出了原函数的__doc__内容

二 递归

1 编写数列

 斐波那契数列指的是这样一个数列 , , , , , , , , , , , , , ,,,,,,,,,,,

函数如下

 def  func(arg1,arg2):
if arg1==:
print arg1,arg2
arg3=arg1+arg2
print arg3
func(arg2,arg3) func(,)

2 递归的返回值

先看下面的一个简单例子

 def n5():
return ''
def n4():
n5()
def n3():
n4()
def n2():
n3()
def n1():
n2()
ret=n1()
print ret 结果None

分析如下

上面的函数首先执行
n1()---n2()--n3()---n4()--n5()
到执行到n5的时候有返回值,n5函数的返回值返回给调用n5函数的函数n4
即res=n5()----def n4(): 但是n4没有返回值,n3也没有返回值,n2也没有返回值,n1也没有返回值,所以最后返回none
改进一下,让他有返回值

 def n5():
return ''
def n4():
return n5()
def n3():
return n4()
def n2():
return n3()
def n1():
return n2()
ret=n1()
print ret 结果 这样让它每次都有返回值

3 看下面的递归例子(改进了一下上边的数列例子)

 def  func(arg1,arg2):
if arg1==:
print arg1,arg2
arg3=arg1+arg2
if arg3>:
return arg3
func(arg2,arg3) ret = func(,)
print ret 结果为None

分析如下

执行第一次func(0,1)没有返回值
执行第二次func(1,1)也没有返回值
..........
当执行到func(610,987)的时候,接着执行上面,arg=1597,满足条件,return返回1597,谁调用的返回给谁,也就是返回给func(610,987),但是在这之前执行func()函数却没有返回值,跟上面的例子差不多,所以最后返回None

改进之后:

 def  func(arg1,arg2):
if arg1==:
print arg1,arg2
arg3=arg1+arg2
if arg3>:
return arg3
return func(arg2,arg3) ret = func(,)
print ret 结果

三模块

模块分为三种:

  • 自定义模块
  • 内置模块
  • 开源模块

自定义模块

1

python之旅5【第五篇】

2

python之旅5【第五篇】

导入模块

 import module
from module.xx.xx import xx
from module.xx.xx import xx as rename
from module.xx.xx import *

导入模块其实就是告诉Python解释器去解释那个py文件

  • 导入一个py文件,解释器解释该py文件
  • 导入一个包,解释器解释该包下的 __init__.py 文件
 模块路径
import sys
print sys.path
结果
['F:\\untitled5\\test', 'F:\\untitled5', 'C:\\Windows\\system32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\site-packages', 'C:\\Python27\\lib\\site-packages\\pip-9.0.1-py2.7.egg']

常用内置模块

os模块

 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间

sys模块

 sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit()
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
上一篇:David McCullough, Jr.为韦斯利高中毕业生演讲〈你并不特别〉


下一篇:函数QFileSystemModelPrivate::_q_fileSystemChanged