Python学习笔记5(文件操作及os模块)

文件

1.文件读取的三部曲:打开—>操作---->关闭
r:(默认)
-只能读,不能写
-读取文件不存在,会报错
FileNotFoundError: [Errno 2] No such file or directory:

w:
-write only
-文件不存在,不报错,并创建新的文件
-文件存在,会清空文件内容并写入新的内容

a:
-write only
-写:文件不存在,不报错,并创建新的文件
-写:不会清空原文件的内容,会在文件末尾追加

a+:
-rw
-文件不存在,不报错
-不会清空文件内容,在末尾追加

r+:
-读写
-文件不存在,报错
-默认情况下,从文件指针所在的位置开始写入

w+:
-rw
-文件不存在,不报错
-会清空文件内容
在这里插入图片描述

# 打开文件
 f = open('/tmp/passwd')
 print(f)				#f是文件对象不能直接打印出内容
 f.close()

在这里插入图片描述

f = open('/tmp/passwd')
# 操作
# 告诉当前文件指针所在的位置
print(f.tell())
content = f.read()
print(content)
print(f.tell())
f.close()

在这里插入图片描述

在这里插入图片描述

f = open('/tmp/passwd')
# 读操作
print(f.read())
f.close()

在这里插入图片描述

f = open('/tmp/passwd','w+')			#'w+'可读可写,'w'只能写不能读
# 写操作
f.write('python')
print(f.tell())
f.seek(0)				#移动指针到文件开头
print(f.tell())
print(f.read())
f.close()

在这里插入图片描述

f = open('/tmp/passwd','w+')
# 判断文件对象拥有的权限
print(f.readable())
print(f.writable())
f.close()

在这里插入图片描述

# 追加操作
f=open('/tmp/passwd','a+')
f.write('123')
f.seek(0)
print(f.read())
f.close()

在这里插入图片描述

  • 关于r+
f = open('/tmp/passwd','r+')
print(f.read())				#从指针所在位置开始读
print(f.tell())				#读完指针所在位置
f.write('hello')				#写操作
print(f.tell())				#写操作执行后,指针位置移动
print(f.read())				#因为指针在hello之后,且hello后无内容,所以为空
f.close()

在这里插入图片描述

非纯文本文件的读取

如果读取图片,音频或视频(非纯文本文件),需要通过二进制的方式进行读取与写入
-读取文本文件
r r+ w w+ a a+ == rt rt+ wt wt+ at at+
-读取二进制文件
rb rb+ wb wb+ ab ab+

# 先读取二进制文件内容
f1 = open('1.jpg', mode='rb')
content = f1.read()
# print(content)
f1.close()

f2 = open('ge.jpg', mode='wb')
# 写入要复制的文件读到的内容
f2.write(content)
f2.close()

在这里插入图片描述

文件的常用操作

默认情况下读取文件的所有内容,小的文件,直接用read读取即可
如果是一个大文件(文件大小>内存大小) readline()

f=open('/tmp/passwd')

print(f.read(3))
# 类似于head -c,读取前几个字符
print(f.read(3))
print(f.tell())	# 查看指针所处位置
# 每次读取一行内容
print(f.readline())
print(f.readline())
f.close()

在这里插入图片描述

f=open('/tmp/passwd')
# 读取文件内容,返回一个列表,列表元素分贝为文件的行内容
print(f.readlines())
f.close()

在这里插入图片描述

# 对于每一行,去掉后面的'\n' ---(列表生成式 map())
f=open('/tmp/passwd')
# 列表生成式
print([line.strip() for line in f.readlines()])
# map高阶函数
print(list(map(lambda x:x.strip(),f.readlines())))
f.close()

在这里插入图片描述

"""
seek:移动指针
    第一个参数:偏移量>0:代表向后移动 <0:代表前移动
    第二个参数:
        0:移动指针到文件开头
        1:当前位置
        2:移动指针到文件末尾
"""
f=open('/tmp/passwd')
print('1:',f.read(3))
print(f.tell())
f.seek(1,0)	#移动到开头后一位
print(f.tell())
f.close()

在这里插入图片描述

文件练习1

"""
创建文件data.txt,文件共100000行,每行存放一个1~100之间的整数
"""
import random

f = open('data.txt','w+')
for i in range(100000):
    f.write(str(random.randint(1,100)) + '\n')
f.seek(0,0)
print(f.read())
f.close()

在这里插入图片描述

with

上下文管理器:打开文件,执行完with语句内容之后,自动关闭文件对象

f = open('/tmp/passwd')
with open('/tmp/passwd') as f:
    print('with语句里面:',f.closed)
    print(f.read())

print('after with语句:',f.closed)

在这里插入图片描述
在这里插入图片描述

#python2(只能这么写)
with open('/tmp/passwd') as f1:
    content = f1.read()
with open('/tmp/passwdbackup','w+') as f2:
    f2.write(content)


with open('/tmp/passwd') as f1,\
    open('/tmp/passwdbackup','w+')as f2:
    # 将第一个文件的内容写入第二个文件中
    f2.write(f1.read())
    f2.seek(0,0)
    f2.read()

在这里插入图片描述

通过yeild实现文件的读取

def bylineread(filename):
    with open(filename)as f:
        line=f.readline()
        while line:
            yield line
            line=f.readline()
# read是一个生成器对象
read=bylineread('/tmp/passwd')
print(read)
# 1.next读取生成器内容
print(next(read))
print(next(read))

在这里插入图片描述

def bylineread(filename):
    with open(filename)as f:
        line=f.readline()
        while line:
            yield line
            line=f.readline()
# # read是一个生成器对象
read=bylineread('/tmp/passwd')
# for
for item in read:
    print(item)

#文件对象是可以for循环遍历的

在这里插入图片描述

# 应用第三方函数库
from collections import Iterable	# 导入对象数据类型
f=open('/tmp/passwd')
print(isinstance(f,Iterable))	#判断变量是否为对象
for i,v in enumerate(f):
    if i==10:	# 取前10个数据
        break
    else:
        print(i,v)

在这里插入图片描述

文件练习2

生成100个MAC地址并写入文件中,MAC地址前6位(16进制)为01-AF-3B
mac地址为12位

import string
import random
print(string.hexdigits)
x = string.hexdigits
#生成16进制数
def macadress():
    mac='01-AF-3B'
    for i in range(3):
        adress=''.join(random.sample(x,2))	#在16进制中随机抽取2个数
        mac=mac+'-'+adress.upper()		#将小写字母转换为大写
    return mac
with open('macadress.txt','w+') as f:
    for i in range(100):
        f.write(macadress()+'\n')
f=open('macadress.txt')
print(f.read())

在这里插入图片描述

文件练习——京东笔试题

京东二面编程题

  1. 生成一个大文件ips.txt,要求1200行, 每行随机为172.25.254.0/24段的ip;
  2. 读取ips.txt文件统计这个文件中ip出现频率排前10的ip;
import random
# 生成存放1200行ip地址的文件的函数
def create_ip_file(filename):
    with open(filename,'a') as f:
        for i in range(1200):
            ip = '172.25.254.'
            x = ''.join(str(random.randint(0,255)))
            IP = ip+x
            f.write(IP+'\n')

# 选出ip出现频率前10的ip的函数
def ip_maxnum(filename):
    # 建立一个空字典
    d={}
    # 调用生成文件的函数
    create_ip_file(filename)
    with open(filename)as f:
    	# 依次遍历返回文件内容的列表
        for key in f.readlines():
            # 若ip存在字典的key值中,则其对应的value值加一
            #否则将该ip附给字典的key值,对应value值为一
            if key.strip() in d:
                d[key.strip()]+=1
            else:
                d[key.strip()]=1
    #将字典的key,value值组成元组,按照value的大小降序
    li=sorted(d.items(),key=lambda x:x[1],reverse=True)
    #打印前10个ip
    print(li[:10])
ip_maxnum('ips.txt')

在这里插入图片描述


# 对于字典里面嵌套字典进行排序
d = {
    '003':{
        'name':'apple1',
        'count':100,
        'price':10
    },
    '002':{
        'name':'apple2',
        'count':200,
        'price':2
    }
}
# 按嵌套字典里的'count'的value值升序
print(sorted(d.items(),key=lambda x:x[1]['count']))
# 按嵌套字典里的'price'的value值升序
print(sorted(d.items(),key=lambda x:x[1]['price']))

在这里插入图片描述

读取文件方式效率比较

#调用在装饰器章节编写的计时器
import functools

import time


def timeit(fun):
    """这是一个装饰器timeit"""
    @functools.wraps(fun) #可以保留被装饰函数的函数名和帮助信息文档
    def wrapper(*args, **kwargs):  # 接收可变参数和关键字参数
        """这是一个wrapper函数"""
        # args:元组  kwargs:字典
        # 在函数执行之前
        start_time = time.time()
        # 执行函数
        res = fun(*args, **kwargs)
        # 函数执行之后
        end_time = time.time()
        print('运行时间为:%.6f' % (end_time - start_time))
        return res
    return wrapper
#判断文件复制是依次打开两个文件效率高还是同时打开两个文件的效率高
@timeit
# 依次打开两个文件
def copy1(old_file,new_file):
    with open(old_file)as f:
        content=f.read()
    with open(new_file,'w')as f:
        f.write(content)
@timeit
# 同时打开两个文件
def copy2(old_file,new_file):
    with open(old_file)as f1,\
        open(new_file,'w')as f2:
        f2.write(f1.read())
copy1('data.txt','data_1.txt')
copy2('data.txt','data_2.txt')
# 对比可知,同时打开两个文件效率高

在这里插入图片描述

os

import os
# 1.返回操作系统类型 值为:posix,是Linux操作系统 值为nt,是windows操作系统
print(os.name)
print('Linux' if os.name == 'posix' else 'Windows')

在这里插入图片描述

# 2.操作系统的详细信息
info = os.uname()
print(info)
print(info.sysname)
print(info.nodename)

在这里插入图片描述

# 3.系统的环境变量
print(os.environ)
# 4.通过key值获取环境变量对应的value值
print(os.environ.get('PATH'))

在这里插入图片描述

#5.判度是否为绝对路径 /tmp/passwd data.txt
# 此判断并不会判断该路径是否存在
print(os.path.isabs('/tmp/passwd3'))
print(os.path.isabs('hello'))

在这里插入图片描述

# 6.生成绝对路径
# 自动将'hello.png'拼接在当前路径下
print(os.path.abspath('hello.png'))
# 将'hello.jpg'拼接在'/tmp'路径下
print(os.path.join('/tmp','hello.jpg'))
print(os.path.join(os.path.abspath('.'),'hello.jpg'))

在这里插入图片描述

# 7.获取目录名或文件名
filename = '/home/kiosk/PycharmProjects/20181117/day09/hello.png'
print(os.path.basename(filename))
print(os.path.dirname(filename))

在这里插入图片描述

# 8.创建目录 删除目录
# 在linux中mkdir mkdir -p创建目录
os.makedirs('img/file1/file2')
os.mkdir('img')
# 只能删除空的目录,不能递归删除
os.rmdir('img')

在这里插入图片描述

# 9.创建文件 删除文件
os.mknod('linux.jpg')
os.remove('linux.jpg')
# 10.文件重命名(mv)
os.rename('data.txt','data1.txt')
# 11.判断文件或目录是否存在
print(os.path.exists('ips.txt'))
print(os.path.exists('data.txt'))
# 12.分离后缀名和文件名
print(os.path.splitext('hello.png'))
# 13.将目录和文件名分离
print(os.path.split('/tmp/hello/hello.png'))

在这里插入图片描述

OS练习1

完成自动创建100个目录,目录名称为学生学号,
学号的前四位均为‘0405’,
学号总计为8位。举例如学号04050001

import os

n=1
for i in range(1,101):
    filename='0405'+('%.4d'%n)
    os.mkdir(filename)
    n+=1
import os

sid = 4050001
for i in range(1,101):
     res_sid = '0' + str(sid + i)
     os.mkdir(res_sid)
sid_pre = '0405'

for i in range(1,101):
    i = str(i)
    i_len = len(i)
    if i_len == 1:
        sid_last = '000' + i

    elif i_len ==2:
        sid_last = '00' + i

    elif i_len == 3:
        sid_last = '0' + i
    else:
        pass
    res_sid = sid_pre + sid_last
    os.mkdir(res_sid)

OS练习2

  1. 在当前目录新建目录img, 里面包含多个文件, 文件名各不相同(X4G5.png)
  2. 将当前img目录所有以.png结尾的后缀名改为.jpg
import os
import string
import random

def gen_code(len=4):
    # 随机生成4位的验证码
    li = random.sample(string.ascii_letters + string.digits, len)
    return ''.join(li)
  
def create_file():
    # 随机生成100个验证码
    li = {gen_code() for i in range(100)}
    os.mkdir('img')
    for name in li:
        os.mknod('img/' + name + '.png')

create_file()
def modify_suffix(dirname, old_suffix, new_suffix):
    """
    :param dirname:操作的目录
    :param old_suffix: 之前的后缀名
    :param new_suffix: 新的后缀名
    :return:
    """
    # 1.判断查找的目录是否存在,如果不存在,报错
    if os.path.exists(dirname):
        # 2.找出所有以old_suffix(.png)结尾的文件
        pngfile = [filename for filename in os.listdir(dirname)
                   if filename.endswith(old_suffix)]
        # pngfiles = filter(lambda filename:filename.endswith(old_suffix)
        #                   ,os.listdir(dirname))
        # 3.将文件名和后缀名分开,留下文件名
        basefiles = [os.path.splitext(filename)[0] for filename in pngfile]
        print(basefiles)
        # 4.文件重命名
        for filename in basefiles:
            #需要加上目录名
            oldname = os.path.join(dirname,filename+old_suffix)
            newname = os.path.join(dirname,filename+new_suffix)
            os.rename(oldname,newname)
            print('%s命名为%s成功' %(oldname,newname))
    else:
        print('%s不存在,不能操作....' %(dirname))

modify_suffix('img','.jpg','.png')

猜你喜欢

转载自blog.csdn.net/mkgdjing/article/details/85047555