##返回函数
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回
def cacl_sum(*args): all_sum = 0 for i in args: all_sum += i return all_sum cacl_sum(1,2,3,4)
但是,如果不需要立刻求和,而是在后面的代码中,根据需要不返回求和的结果,而是返回求和的函数:如果
不需要立刻求和,而是在后面的代码中根据需要不返回求和的结果,而是返回求和的函数。如下:在函
数lazy_sum中又定义了函数cacl_ sum,并且内部函数cacl_sum可以引用外部函数lazy_sum 的
参数和局部变量,当 lazy_sum 返回函数cacl_sum时,相关参数和变量都保存在返回的函数中,这
种函数形式称为“闭包(Closure)”
def lazy_sum(*args): def cacl_sum(): all_sum = 0 for i in args: all_sum += i return all_sum return cacl_sum f = lazy_sum(1,2,3,4) #调用 lazy_sum() 时,返回的并不是求和结果,而是求和函数
f () #调用函数 f 时,才真正计算求和的结果
请再注意一点,当我们调用 lazy_sum() 时,每次调用都会返回一个新的函数,即使传入相同的参数:
>>> f1 = lazy_sum(1, 3, 5, 7, 9)
>>> f2 = lazy_sum(1, 3, 5, 7, 9)
>>> f1==f2
Fals
##装饰器(Decorator)
用来装饰函数,想要增强原有函数的功能,但不希望修改现有函数的定义,在代码运行期间动态增加功能的
方式称为装饰器;装饰器的实质是返回函数的高阶函数。
实例一 def atminfo(fun): ##作为一个装饰器,接受一个函数作为参数,并返回一个函数。 def wrapped(): print "....中国建设银行ATM..." fun() return wrapped @atminfo ##装饰器的语法糖 def login(): print "登陆界面" login() 由于atminfo( )是一个装饰器,返回一个函数,所以,原来的login() 函数仍然存在,只是现 在同名的now变量指向了新的函数,于是调用login()将执行新函数,即在 atminfo() 函数 中返回的wrapper() 函数。 wrapper( ) 函数的参数定义是 (*args, **kw) ,因此,wrapper()函数可以接受任意参 数的调用。在 wrapper()函数内,首先打印日志,再紧接着调用原始函数。
@atminfo 放在login()函数的定义处相当于login = atminfo(login)
装饰器带参数:
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,如上述实例,
在用户登陆时显示"ATM登陆系统","ATM查询系统"。。。
装饰器之函数记时器:
运行一个函数,并打印出运行给函数所用的时间
import time def timmer(fun): def warpped(*args): ##形参 start_time = time.time() fun(*args) end_time = time.time() print "function%s runs %s seconds" %(fun.__name__,end_time-start_time) return warpped @timmer def add(x,y): print x*y add(2,3) @timmer def wait(): print "Please wait a moment" wait() 输出:
python装饰器之引入日志
创建一个引入日志的装饰器,使得添加@mylog的函数都能自动保存日志,日志格式:时间,函数,函数参数
输出:
将所获取到的日志写入到文件里面,只需将print操作变为文件读写操作:
file = open("/var/log/mylog" ,"a+")
file.wirte("%s run %s(%s,%s)\n" %(time.time(),fun.__name__,args,kwargs))
file.close( )
##文件管理
文件操作的完整过程
f=open("/mnt/hello","rw/a[b]") ##打开文件
f.read( )/f.write() ##读文件/写文件
f.close( ) ##关闭文件
-文件的打开文件的命令为open,返回值是一个文件对象,打开方式为只读“r”
text =open("/etc/passwd") ## 如果文件不存在, open() 函数就会抛出一个 IOError 的错误,
并且给出错误码和详细的信息告诉你文件不存在
-读取文件内容:
text.read( ) ##如果文件打开成功,接下来,调用 read() 方法可以一次读取文件的全部内容;
• 如果文件很小, read( ) 一次性读取最方便;
• 如果不能确定文件大小,反复调用 read(size)
• 比较保险;如果是配置文件,调用 readlines( )
readline方法依次读取文件,仅返回一行文件信息;
readlines方法以列表方式返回文件信息;默认保留换行符
-f.write( )
- f.writeline( ) ##可以写入多行文本
-关闭文件:
text.close( ) ###文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源
•二进制文件
要读取二进制文件,比如图片、视频等等,用 'rb' 模式打开文件即可
>>> f = open('/root/test.jpg', 'rb')
>>> f.read()
'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
•open函数的模式
r 以读的方式打开,定位到文件开头 , 默认的 mode
r+ 以读写的方式打开,定位文件开头 , 可以写入内容到文件
w 以写的方式打开,打开文件的时候会清空文件的内容,并且不能读
w+ 以读写的方式打开,定位到文件头,并且打开文件的时候也会清空文件的内容
a 以写的方式打开,定位到文件的末尾,是一个追加的操作 , 但并不允许读
a+ 以读写的方式打开,定位到文件的末尾,追加的方式。
在使用以上 mode 打开文件的时候,如果增加了b 模式,表示以二进制方式打开
f.seek( ) 需要传两个参数:
第一个:偏移量 如果>0,代表向右移动的字符,反之,代表向左移动的字符;
第二个参数:0:文件开头 1 :当前位置 2.文件末尾
f.tell( )函数,返回当前文件指针的偏移量:
file 对象是一个迭代器:
next() 方法 , 一行一行的读 , 每次读取一行
也可以使用for循环遍历:
-- 文件的内置属性
f.closed( ) 返回bool值,判断文件对象的状态
f.mode( ) 查看文件的打开模式
f.name( ) 查看文件名
一般情况打开一个文件,经过操作之后,都要显式的执行xx.close() 将文件关闭 .with 用于需要打开、关闭成对的操作,可以自动关闭打开对象 .with expression as obj:# 将打开的对象赋值给 obj
#obj 的作用域只在 with 语句中
显示文件中的所有行,但是忽略以“ # ” 开头的行
把/etc/passwd 中的“root” 替换为“westos”,并写入到/mnt/passwd中
来源:CSDN
作者:rockstics
链接:https://blog.csdn.net/rockstics/article/details/78968010