1. 程式人生 > >python基礎--檔案操作,os模組

python基礎--檔案操作,os模組

檔案操作

檔案讀取的三部曲:開啟—>操作---->關閉
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)
操作
告訴當前檔案指標所在的位置
print(f.tell())
content = f.read()
print(content)
print(f.tell())
讀操作
print(f.read())
寫操作
f.write('python')
判斷檔案物件擁有的許可權
print(f.readable())
print(f.writable())
f.write('python')
關閉
print(f.read())
print(f.tell())
f.close()


f = open('/tmp/passwd','r+')
print(f.read())
f.write('123')
print(f.read())
f.close()

非純文字檔案的讀取

如果讀取圖片,音訊或視訊(非純文字檔案),需要通過二進位制的方式進行讀取與寫入
-讀取文字檔案
r r+ w w+ a a+ == rt rt+ wt wt+ at at+
-讀取二進位制檔案
rb rb+ wb wb+ ab ab+

先讀取二進位制檔案內容

f1 = open('1111.jpg', mode='rb')
content = f1.read()
print(content)
f1.close()

f2 = open('hello.jpg', mode='wb')

寫入要複製的檔案讀到的內容

f2.write(content)
f2.close()

檔案的常用操作

f = open(’/tmp/passwd’, ‘r’)

預設情況下讀取檔案的所有內容,小的檔案,直接用read讀取即可
如果是一個大檔案(檔案大小>記憶體大小) readline()

#類似於head -c
print(f.read(3))
#4g 5g
每次讀取一行內容
print(f.readline())
print(f.readline())
讀取檔案內容,返回一個列表,列表元素分貝為檔案的行內容
print(f.readlines())
print(f.readable())

對於每一行,去掉後面的'\n' ---(列表生成式 map())
print([line.strip() for line in f.readlines()])
print(list(map(lambda x:x.strip(),f.readlines())))

f.close()


f = open('/tmp/passwd','rb')
f.write('hello') #從指標所在位置寫入,寫的就是字串的內容
f.writelines(['a','b']) #將列表中的每個元素寫入檔案
f.writable()
指標的操作
print(f.tell())
print('1:',f.read(3))
print(f.tell())
f.seek(0,2)
"""
seek:移動指標
    第一個引數:偏移量>0:代表向後移動 <0:代表前移動
    第二個引數:
        0:移動指標到檔案開頭
        1:當前位置
        2:移動指標到檔案末尾
"""
print(f.tell())
f.close()

檔案練習

建立檔案data.txt,檔案共100000行,每行存放一個1~100之間的整數

import random

f=open('data.txt','a+')
for i in range(100000):
    f.write(str(random.randint(1,101))+'\n')
f.seek(0,0)
#print(f.read())
print([i.strip() for i in f.readlines()])
#print(list(map(lambda x:x.strip(),f.readlines())))
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)

#python3
with open('/tmp/passwd') as f1,\
    open('/tmp/passwdbackup','w+')as f2:
    # 將第一個檔案的內容寫入第二個檔案中
    f2.write(f1.read())
    # f2.seek(0,0)
    # f2.read()

通過yield實現檔案的讀取

def bylineread(fimename):
    with open(fimename) as f:
        line = f.readline()
        while line:
            yield line
            line = f.readline()

read是一個生成器物件
read = bylineread('data.txt')
print(read)
1.next讀取生成器內容
print(next(read))
print(next(read))

for
for item in read:
    print(item)

檔案物件是可以for迴圈遍歷的
from collections import Iterable

f = open('data.txt')
print(isinstance(f,Iterable))
for i,item in enumerate(f):
    if i == 10:
        break
    print(i,item)

檔案練習–生成MAC地址

生成100個MAC地址並寫入檔案中,MAC地址前6位(16進位制)為01-AF-3B
01-AF-3B-xx-xx-xx
-xx
01-AF-3B-xx
-xx
01-AF-3B-xx-xx
-xx
01-AF-3B-xx-xx-xx

import string
import random

#隨機生成一個MAC地址的函式
def creat_mac():
    MAC= '01-AF-3B'
    # 生成16進位制的數
    hex_num = string.hexdigits
    for i in range(3):
        # 從16進位制字串中隨機選出2個數來(返回值為列表)
        n = random.sample(hex_num,2)
        # 拼接列表中的內容,將小寫字母轉換為大寫
        sn = '-' + ''.join(n).upper()
        MAC += sn

    return MAC

#主函式,隨機生成100個MAC地址
def main():
    # 以寫的方式開啟檔案
    with open('mac.txt','w') as f:
        for i in range(100):
            mac= creat_mac()
            print(mac)
            # 每生成一個MAC地址,存入檔案(注意換行)
            f.write(mac+'\n')

main()

在這裡插入圖片描述

檔案練習–生成ip和排列ip

京東二面程式設計題
1.生成一個大檔案ips.txt,要求1200行, 每行隨機為172.25.254.0/24段的ip;
2.讀取ips.txt檔案統計這個檔案中ip出現頻率排前10的ip;

import random

def create_ip_file(filename):
    ips = ['172.25.254.' + str(i) for i in range(0,255)]
    print(ips)
    with open(filename,'a+') as f:
        for count in range(1200):
            f.write(random.sample(ips,1)[0] + '\n')


#create_ip_file('ips.txt')

def sorted_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
    sorte_ip = sorted(ips_dict.items(),key=lambda
        x:x[1],reverse=True)[:count]
    return sorte_ip

print(sorted_ip('ips.txt'))

在這裡插入圖片描述

讀取檔案方式效率對比

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 read1(filename):
     # for 迭代
     with open(filename) as f:
         for line in f:
             # 對檔案的處理操作
             line = int(line.strip())
             line = line + 1

@timeit
def read2(filename):
     with open(filename) as f:
         for line in f.readlines():
             line = int(line.strip())
             line = line+1
#
#
#
#
#
read1('data.txt')
read2('data.txt')

@timeit
def copy(sourcefile,destfile):
    with open(sourcefile) as f1:
        content = f1.read()
        with open(destfile,'w') as f2:
            f2.write(content)

@timeit
def copy1(sourcefile,destfile):
    with open(sourcefile) as f1,open(destfile,'w')as f2:
        # for line in f1:
        #     f2.write(line)
        f2.write(f1.read())

copy('data.txt','data_1.txt')
copy1('data.txt','data_2.txt')

通過計時器對進行裝飾,發現python內建的方法的執行時間明顯短。

os模組

對於字典裡面巢狀字典進行排序
 d = {
     '003':{
         'name':'apple1',
         'count':100,
         'price':10
     },
     '002':{
         'name':'apple2',
         'count':200,
         'price':2
     }

 }
 print(d.items()) #[('key',{}),(),()]

 x:('003', {'name': 'apple1', 'count': 100, 'price': 10})
 print(sorted(d.items(),key=lambda x:x[1]['count']))
 print(sorted(d.items(),key=lambda x:x[1]['price']))

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.生成絕對路徑
print(os.path.abspath('hello.png'))
print(os.path.join('/home/kiosk','hello.png'))
print(os.path.join(os.path.abspath('.'),'hello.png'))

7.獲取目錄名或檔名
filename = '/home/kiosk/PycharmProjects/20181117/day09/hello.png'
print(os.path.basename(filename))
print(os.path.dirname(filename))

8.建立目錄 刪除目錄
mkdir mkdir -p
os.makedirs('img/file1/file2')
os.mkdir('img')
os.rmdir('img')


9.建立檔案 刪除檔案
os.mknod('00_ok.txt')
os.remove('00_ok.txt')


10.檔案重新命名(mv)
os.rename('data.txt','data1.txt')

11.判斷檔案或目錄是否存在
print(os.path.exists('ips.txt'))

12.分離字尾名和檔名
print(os.path.splitext('hello.png'))

13.將目錄和檔名分離
print(os.path.split('/tmp/hello/hello.png'))

os練習–建立學生目錄

完成自動建立100個目錄,目錄名稱為學生學號,
學號的前四位均為‘0405’,
學號總計為8位。舉例如學號04050001

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練習

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')

在這裡插入圖片描述