真正的无知不是知识的贫乏, 而是拒绝获取知识! ——波普尔 (哲学家 思想家)
[toc]
##目标
掌握常用的文件目录操作
学习with关键字
练习题
第一部分 os模块 os模块是Python标准库中的一个用于访问操作系统相关功能的模块,os模块提供了一种可移植的使用操作系统功能的方法。
1. os模块的主要功能:
系统相关
目录及文件操作
执行命令和管理进程
2. 文件及目录相关
方法
说明
os.mkdir
创建目录
os.rmdir
删除目录
os.rename
重命名
os.remove
删除文件
os.getcwd
获取当前工作路径
os.walk
遍历目录
os.path.join
连接目录与文件名
os.path.split
分割文件名与目录
os.path.abspath
获取绝对路径
os.path.dirname
获取路径
os.path.basename
获取文件名或文件夹名
os.path.splitext
分离文件名与扩展名
os.path.isfile
判断给出的路径是否是一个文件
os.path.isdir
判断给出的路径是否是一个目录
背诵这种真的没啥意义,不如来个实例记得快些。网上找了个实例,来源python 文件操作练习题 , 稍加改动,还有bug ,但包含了一些常用的方法。
import oswhile True : mulu = input('请输入目录:' ) if os.path.exists(mulu): os.chdir(mulu) ret = os.listdir(os.getcwd()) print(ret) lst1 = [] lst2 = [] for i in ret: if os.path.isfile(i): lst1.append(i) else : lst2.append(i) print('文件:%s' % lst1) print('文件夹:%s' % lst2) ret1 = input('请选择操作:全部文件添加前缀(a) 全部删除前缀(s) 添加文件(d) 删除文件(f) 单个文件重命名(g):' ) if ret1.upper() == 'A' : a = input('请输入所要添加的前缀:' ) for i in ret: os.rename(i, a + i) print('添加成功' ) elif ret1.upper() == 'S' : a = input('请输入所要删除的前缀:' ) for i in ret: os.rename(i, i.replace(a, '' , 1 )) print('删除前缀成功' ) elif ret1.upper() == 'D' : file_name = input('请输入所要添加文件名称:' ) with open(file_name, mode='w' ) as f: pass print('添加文件成功' ) elif ret1.upper() == 'F' : del_name = input('请输入所要删除的文件名:' ) os.remove(del_name) print('删除文件成功' ) elif ret1.upper() == 'G' : name = input('请输入原始文件名[old name]:' ) if name.strip() == '' : name = input('不可为空,请输入原始文件名[old name]:' ) newName = input('请输入新的文件名[new name]:' ) if newName.strip() == '' : newName = input('不可为空,请输入新的文件名[old name]:' ) os.rename(name, newName) print('修改成功' ) os.chdir('..' ) else : print('输入有误,请重新输入' )
第二部分 with关键字
第一部分中的with究竟是什么意思?为何要用with呢?
pyhton2.5中加入with, 常用来替换try ... except ... finally ....
我们采用事务链接时,会着这样判断
db.begin() try : except : db.rollback() raise else : db.commit()
如果将发起事务请求的操作变成可以支持with关键字的,那么用像这样的代码就可以了:
第一部分的with就是保证读取文件内容时,不论出现什么意外,都保证最终关闭。
with open('file.txt' ) as f: content = f.read()
with 的一般执行过程 一段基本的with表达式,其结构是这样的:
其中:EXPR可以是任意表达式;as VAR是可选的。其一般的执行过程是这样的:
计算EXPR,并获取一个上下文管理器。
上下文管理器的exit() 方法被保存起来用于之后的调用。
调用上下文管理器的enter() 方法。
如果with表达式包含as VAR,那么EXPR的返回值被赋值给VAR。
执行BLOCK中的表达式。
调用上下文管理器的exit() 方法。如果BLOCK的执行过程中发生了一个异常导致程序退出,那么异常的type、value和traceback(即sys.exc_info()的返回值)将作为参数传递给exit() 方法。否则,将传递三个None。
实现类似的with过程 class transaction (object) : def __init__ (self, db) : self.db = db def __enter__ (self) : self.db.begin() def __exit__ (self, type, value, traceback) : if type is None : db.commit() else : db.rollback()
基于装饰器的方法或更相信教程可参考Python 中的关键字with详解
第三部分 习题 狗东二面笔试题
生成一个大文件ips.txt,要求1200行,每行随机为172.25.254.0/24段的ip;
读取ips.txt文件统计这个文件中ip出现频率排前10的ip;
分析
172.25.254.0/24,前24位为网络号,后八位为主机号,[0-255);
1200行,写入ips.txt文件
统计次数,抽出前十条
import randomdef create_ip_file (filename) : ip = ['172.25.254.' + str(i) for i in range(0 , 255 )] with open(filename, 'a+' ) as f: [f.write(random.sample(ip, 1 )[0 ] + '\n' ) for i in range(1200 )] create_ip_file('ips.txt' ) def sorted_by_ip (filename, count=10 ) : ips_dict = dict() with open(filename) as f: for ip in f: if ip in ips_dict: ips_dict[ip] += 1 else : ips_dict[ip] = 1 print(ips_dict.items()) sorted_ip = sorted( ips_dict.items(), key=lambda x: x[1 ], reverse=True )[:count] return sorted_ip print(sorted_by_ip('ips.txt' ))
结果
[('172.25.254.49\n' , 14 ), ('172.25.254.80\n' , 12 ), ('172.25.254.172\n' , 11 ), ('172.25.254.65\n' , 11 ), ('172.25.254.45\n' , 10 ), ('172.25.254.30\n' , 10 ), ('172.25.254.8\n' , 10 ), ('172.25.254.196\n' , 9 ), ('172.25.254.53\n' , 9 ), ('172.25.254.121\n' , 9 )]
参考Python 中的关键字with详解 python文件操作练习题