python(七) 装饰器 文件操作

試著忘記壹切 提交于 2019-11-28 10:00:40

##返回函数

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回

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中


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!