1. 程式人生 > 其它 >檔案操作和函式簡介

檔案操作和函式簡介

檔案操作和函式簡介

檔案內游標的移動

#大前提:檔案內指標的移動是Bytes為單位的,唯獨t模式下的read讀取內容個數是以字元為單位
 f.read(3)
 with open('a.txt',mode='rt',encoding='utf-8') as f:
     data=f.read(3)
     print(data)

 with open('a.txt',mode='rb') as f:
     data=f.read(3)
     print(data.decode('utf-8'))
    
    
f.seek(指標移動的位元組數,模式控制): 控制檔案指標的移動
模式控制:
0: 預設的模式,該模式代表指標移動的位元組數是以檔案開頭為參照的
1: 該模式代表指標移動的位元組數是以當前所在的位置為參照的1
2: 該模式代表指標移動的位元組數是以檔案末尾的位置為參照的
強調:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用

f.tell()檢視檔案指標當前距離檔案開頭的位置


# 0模式詳解
 
with open('a.txt',mode='rt',encoding='utf-8') as f:
     f.seek(4,0)
     print(f.tell())
     print(f.read())

 with open('a.txt',mode='rb') as f:
     # f.seek(4,0)
     f.seek(2,0)
     print(f.tell())
     print(f.read().decode('utf-8'))


 with open('a.txt',mode='rt',encoding='utf-8') as f:
     f.seek(5,0)
     print(f.read())


# 1模式詳解
 
with open('a.txt',mode='rb') as f:
     f.seek(3,1)
     print(f.tell())
     f.seek(4,1)
     print(f.tell())
     print(f.read().decode('utf-8'))

# 2模式詳解
 
with open('a.txt',mode='rb') as f:
     f.seek(-9,2)
     data=f.read()
     print(data.decode('utf-8'))

# tail -f access.log  實時檢測檔案內是否有新增內容並打印出來

with open('access.log',mode='rb') as f:
    f.seek(0,2)
    while True:
        line=f.readline()
        if len(line) == 0:
            # 沒有內容
            continue
        else:
            print(line.decode('utf-8'),end='')

檔案的修改

#方式一:
硬碟空間無法修改,硬碟中的資料更新都是用新的內容覆蓋舊的內容
記憶體控制可以修改

#程式碼示例:
with open('a.txt','r+t',encoding='utf-8') as f:
    f.seek(4,0)
    print(f.tell())
    f.write('我擦嘞')
    
'''    硬碟上的資料有兩個狀態
		佔有態與自由態
			我們刪除資料其實就是將資料原來的位置標記成自由態
			之後如果有新的資料進來了並且落到了自由態位置那麼直接覆蓋
ps:自己不用的手機和電腦 不要輕易的賣掉
	先刪除所有的資料 然後找一些無關緊要的資料儲存一遍(比如500G的葫蘆娃)
	之後再刪除一次 '''


#方式二:
檔案對應的是硬碟空間,硬碟不能修改應為檔案本質也不能修改,
將硬碟中檔案內容讀入記憶體,然後在記憶體中修改完畢後再覆蓋回硬碟

# 1. 將檔案內容發一次性全部讀入記憶體,然後在記憶體中修改完畢後再覆蓋寫回原檔案
# 優點: 在檔案修改過程中同一份資料只有一份
# 缺點: 會過多地佔用記憶體
# with open('db.txt',mode='rt',encoding='utf-8') as f:
#     data=f.read()

# with open('db.txt',mode='wt',encoding='utf-8') as f:
#     f.write(data.replace('kevin','SB'))



# 2. 以讀的方式開啟原檔案,以寫的方式開啟一個臨時檔案,一行行讀取原檔案內容,修改完後寫入臨時檔案...,刪掉原檔案,將臨時檔案重新命名原檔名
# 優點: 不會佔用過多的記憶體
# 缺點: 在檔案修改過程中同一份資料存了兩份
import os

with open('db.txt',mode='rt',encoding='utf-8') as read_f,\
        open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
    for line in read_f:
        wrife_f.write(line.replace('SB','kevin'))

os.remove('db.txt')
os.rename('.db.txt.swap','db.txt') #重新命名檔案


函式的簡介:

#函式是python為了程式碼最大程度地重用和最小程式碼冗餘而提供的基本資料結構。 函式是一種設計工具,可能將複雜的程式,分解成可以管理的塊。

在python中可以建立四種函式:

1.全域性函式:定義在模組中
2.區域性函式:巢狀在其他函式中
3.lambda函式:表示式
4.方法:與特定資料型別關聯的函式,並且只能與資料型別關聯一起使用。
 
''' 我們需要在不同的地方 反覆執行相同的程式碼>>>:函式
 我們需要在相同的地方 反覆執行相同的程式碼>>>:迴圈'''

#程式碼示例:
def my_len():
    n = 0
    for i in s:
        n += 1
    print('字串中字元的個數', n)
# print(my_len())
"""
上述程式碼與真正的len差距
    1.真正的len可以統計指定資料的元素個數
        而我們的len目前只能統計指定的資料
    2.真正的len執行完成後有結果
        而我們的len執行完成後結果是None
"""

函式的語法結構

def 函式名(引數1,引數2):
    '''函式的註釋'''
    函式體程式碼
    return 返回值

1.def	
	是定義函式的關鍵字
2.函式名
	函式名類似於是變數名 指代函式體程式碼 命名與變數名一致
3.括號
	定義函式的時候 函式名後面肯定要先寫括號
4.引數
	類似於使用函式的時候 給函式內部傳遞的資料 可以不寫 或者單個、多個
5.冒號
	定義函式也需要有縮排的程式碼塊
6.函式的註釋
	用於解釋函式的主要功能、使用方法等說明性文字
7.函式體程式碼
	函式的核心功能 也是我們將來編寫的核心
8.return
	後面跟什麼 那麼執行完函式之後就會返回什麼

函式的呼叫形式

#函式的呼叫形式:

語句形式:

func()

#表示式形式:

res = func2(10)

#函式當另一個函式的引數傳入一個函式呼叫:

res = func3(func2(10))

函式的作用域

python建立、改變或者查詢變數名都是在名稱空間進行

在程式碼中變數名被賦值的位置決定了其能被訪問到的範圍

函式定義了本地作用域,而模組定義了全域性作用域

每個模組都是一個全域性作用域,因此全域性作用域僅限單個程式檔案。

每次對函式的呼叫都會建立一個新的本地作用域,賦值的變數除非宣告為全域性變數,否則均為本地變數。

所有的變數名都可以歸納為本地、全域性或者內建的變數。

#內建名稱空間:python直譯器自帶的名字,python直譯器啟動就會生成。

#全域性名稱空間:檔案和模組級別定義的名字都會。

#區域性名稱空間:定義在函式內部的名字。區域性名稱空間只有在函式呼叫時才會生效,呼叫結束失效。

#變數名解析:LEGB原則,作用域越小優先順序越高,某個變數,現在本地函式找,找不到去上一層函式找,再找不到就去模組全域性變數找,再找不到就去系統內建的變數找,最後還是內找不到,丟擲異常。

LEGB原則:

備註:

global定義全域性變數,可以在函式內部改變函式外面定義的全域性變數的賦值

locals區域性作用域,可以改變函式內變數賦值,無論函式內套多少層函式。