學習python,從入門到放棄(10)
學習python,從入門到放棄(10)
檔案內的游標移動
-
基本移動
read 在文字模式下,括號內的數字表示的是讀取指定的字元個數,但不會從頭讀取,會繼續讀取。
with open(r'a.txt', 'r', encoding='utf8') as f: print(f.read(3)) # hel print(f.read(3)) # lo
read 在二進位制模式下,括號內的數字表示的是讀取指定的位元組數 unicode 所有的字元都是用 2bytes 表示一個字元,而utf8中文用 3bytes 來表示一個字元,英文用 1bytes 來表示一個字元,同樣是繼續讀取。
with open(r'a.txt', 'rb') as f: print(f.read(9).decode('utf8')) # hello wor print(f.read(1).decode('utf8')) # l
-
控制移動
.seek() 方法可以控制游標的移動,在文字模式下移動的單位也是位元組數。
.seek(offset,whence)
offset :控制移動的位元組數
whence:控制模式
控制模式0:讓游標先移動到檔案開頭,支援文字模式和二進位制模式
控制模式1:讓游標先停留在當前位置,只支援二進位制模式
控制模式2:讓游標先移動到檔案末尾,只支援二進位制模式
with open(r'a.txt','r',encoding='utf8') as f: print(f.read()) # hello world你好世界 f.seek(3, 0) print(f.read()) # lo world你好世界 with open(r'a.txt', 'rb') as f: print(f.read(3).decode('utf8')) # hel f.seek(3, 1) # 基於當前位置 繼續往後移動三個位元組 f.seek(-3, 2) # 基於檔案末尾 往前移動三個位元組 print(f.tell()) # 獲取游標基於檔案開頭的位元組數 20 print(f.read().decode('utf8')) # 界
檔案的修改
硬碟上的資料有兩個狀態,佔有態與自由態,我們刪除資料其實就是將資料原來的位置標記成自由態,之後如果有新的資料進來了並且落到了自由態位置那麼直接覆蓋。所以自己不用的手機和電腦,不要直接賣掉,應該先刪除所有的資料,然後找一些無關緊要的資料儲存一遍。
將檔案內容發一次性全部讀入記憶體,然後在記憶體中修改完畢後再覆蓋寫回原檔案,優點是在檔案修改過程中同一份資料只有一份,缺點是會過多地佔用記憶體。
with open('b.txt', mode='r', encoding='utf-8') as f:
data = f.read()
print(data)
with open('b.txt', mode='w', encoding='utf-8') as f:
f.write(data.replace('hello', '你好'))
with open('b.txt', mode='r', encoding='utf-8') as f:
data = f.read()
print(data)
也可以以讀的方式開啟原檔案,以寫的方式開啟一個臨時檔案,一行行讀取原檔案內容,修改完後寫入臨時檔案,刪掉原檔案,將臨時檔案重新命名原檔名。優點是不會佔用過多的記憶體,缺點是在檔案修改過程中同一份資料存了兩份。
import os
with open('b.txt', 'r', encoding='utf-8') as read_f, \
open('.b.txt.swap', 'w', encoding='utf-8') as wrife_f:
for line in read_f:
wrife_f.write(line.replace('你好', 'hello'))
os.remove('b.txt') # 刪除檔案
os.rename('.b.txt.swap', 'b.txt') # 重新命名檔案
# 你好 world 》》》hello world
函式
自定義函式,當我們需要在不同的地方完成相同的操作時,編寫兩段一樣的程式碼就顯得很冗長很沒有美感,這時候就需要自己定義一個函式,將這個操作放在這個函式裡,當需要時就可以直接拿來使用了。
s = 'hello world'
print(len(s)) # 11
def my_len():
n = 0
for i in s:
n += 1
print('字串中字元的個數',n)
my_len() # 字串中字元的個數 11
-
語法結構
def 函式名(引數1,引數2): '''函式的註釋''' 函式體程式碼 return 返回值
def 用於告訴計算機下面我要開始自定義函式啦
函式名類似與變數名,當我們要用這個函式時直接寫它的函式名就可以使用了
括號要緊跟在函式名後面
引數用於在使用函式時進行內部資料的傳遞。
冒號表示需要縮排的程式碼塊
函式的註釋可以告訴別人該函式的用途
函式體程式碼是函式的核心功能,是我們需要編寫的核心
return後面跟著返回值,表面需要返回的資料是什麼
定義函式的過程不會執行函式體程式碼,只會檢測語法。
總結
今天學習了昨天檔案操作的補充,還有學習了新的自定義函式,自定義函式學會了之後會使我們的程式碼更加簡練也會更加美觀。
作業
嘗試著使用函式寫註冊登入
但是我寫了 cmd 的部分
import pathlib
chances = 1
is_l_again = False
is_run = True
path = pathlib.Path("userinfo.txt") # 當不存在userinfo時自動建立,其中只有一個使用者jason
if not path.is_file():
with open('userinfo.txt', 'w', encoding='utf8') as f:
f.write('jason|123')
def cmd():
"""
登入成功後的cmd
"""
print('登入成功,歡迎你,%s' % in_username)
print('輸入quit退出系統')
while True:
cmd = input('>>>')
if cmd == 'quit':
print("再見,%s" % in_username)
break
else:
print(cmd)
return None
while is_run:
username = []
password = []
with open('userinfo.txt', 'r', encoding='utf8') as f:
data = f.readlines()
for i in range(len(data)):
username.append(data[i].split('|')[0])
password.append(data[i].split('|')[1])
l_or_r = input('登入/註冊?請輸入L/R')
if l_or_r == 'l' or l_or_r == 'L':
while chances <= 3:
in_username = input('username:').strip()
in_password = input('password:').strip()
if in_username in username and in_password == password[username.index(in_username)]:
cmd()
is_run = False
break
else:
print('使用者名稱或密碼錯誤,剩餘嘗試次數為 %d 次' % (3 - chances))
if chances == 3:
while True:
again = input('是否再次嘗試 y/n')
if again == 'y' or again == 'Y':
is_l_again = True
break
elif again == 'n' or again == 'N':
break
else:
print("請輸入y/n")
continue
chances += 1
if is_l_again:
chances = 1
is_l_again = False
elif l_or_r == 'r' or l_or_r == 'R':
while True:
in_username = input('username:').strip()
if in_username in username:
print('使用者名稱已存在,請重新輸入,如已註冊,想返回登入介面在 username 處輸入:back')
continue
elif in_username == 'back':
break
in_password1 = input('password:').strip()
in_password2 = input('password again:').strip()
if in_password1 != in_password2:
print('兩次輸入的密碼不一致,請重新輸入')
continue
else:
print('註冊成功')
with open('userinfo.txt', 'a', encoding='utf8') as f:
f.write('\n')
f.write(in_username)
f.write('|')
f.write(in_password1)
cmd()
is_run = False
break