Python Language
Filer & mappar I / O
Sök…
Introduktion
När det gäller att lagra, läsa eller kommunicera data är det nödvändigt och enkelt att arbeta med filerna i ett operativsystem med Python. Till skillnad från andra språk där filinmatning och utdata kräver komplexa läs- och skrivobjekt, förenklar Python processen endast med kommandon för att öppna, läsa / skriva och stänga filen. Detta ämne förklarar hur Python kan gränssnitt med filer i operativsystemet.
Syntax
- file_object = öppen (filnamn [, access_mode] [, buffering])
parametrar
Parameter | detaljer |
---|---|
filnamn | sökvägen till din fil eller, om filen finns i arbetskatalogen, filens filnamn |
access_mode | ett strängvärde som avgör hur filen öppnas |
buffrande | ett heltal som används för valfri linjebuffring |
Anmärkningar
Undvika den plattform som kodar helvete
När du använder Pythons inbyggda open()
är det bästa sättet att alltid passera encoding
, om du tänker att din kod ska köras över plattformen. Anledningen till detta är att systemets standardkodning skiljer sig från plattform till plattform.
Medan linux
system faktiskt använder utf-8
som standard, är detta inte nödvändigtvis sant för MAC och Windows.
För att kontrollera ett systems standardkodning, prova detta:
import sys
sys.getdefaultencoding()
från vilken pytontolk som helst.
Därför är det klokt att alltid avskilja en kodning, för att se till att strängarna du arbetar med är kodade som vad du tror att de är, vilket säkerställer kompatibilitet mellan plattformar.
with open('somefile.txt', 'r', encoding='UTF-8') as f:
for line in f:
print(line)
Fillägen
Det finns olika lägen som du kan öppna en fil med, som anges av mode
parameter. Dessa inkluderar:
'r'
- läsläge. Standarden. Det låter dig bara läsa filen, inte att ändra den. När du använder detta läge måste filen finnas.'w'
- skrivläge. Det kommer att skapa en ny fil om den inte finns, annars raderar du filen och låter dig skriva till den.'a'
- lägg till läge. Det kommer att skriva data till slutet av filen. Det raderar inte filen och filen måste finnas i det här läget.'rb'
- läsläge i binär. Detta liknarr
förutom att avläsningen tvingas i binärt läge. Detta är också ett standardval.'r+'
- läsläge plus skrivläge samtidigt. Detta gör att du kan läsa och skriva in filer på samma gång utan att behöva användar
ochw
.'rb+'
- läs- och skrivningsläge i binär. Samma somr+
förutom att data finns i binär'wb'
- skrivläge i binär. Samma somw
förutom att data är binära.'w+'
- skriv- och läsläge. Exakt samma somr+
men om filen inte finns görs en ny. Annars skrivs filen över.'wb+'
- skriv- och läsläge i binärt läge. Samma somw+
men data finns i binär.'ab'
- läggs till i binärt läge. Liknara
förutom att uppgifterna är binära.'a+'
- lägg till och läsa. Liknarw+
eftersom det kommer att skapa en ny fil om filen inte finns. Annars är filpekaren i slutet av filen om den finns.'ab+'
- lägg till och läsläge i binär. Samma soma+
förutom att data är binära.with open(filename, 'r') as f: f.read() with open(filename, 'w') as f: f.write(filedata) with open(filename, 'a') as f: f.write('\n' + newdata)
r | r + | w | w + | en | a + | |
---|---|---|---|---|---|---|
Läsa | ✔ | ✔ | ✘ | ✔ | ✘ | ✔ |
Skriva | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Skapar fil | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ |
Raderar fil | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
Första position | Start | Start | Start | Start | Slutet | Slutet |
Python 3 har lagt till ett nytt läge för exclusive creation
så att du inte av misstag trunkerar eller skriver över och befintlig fil.
-
'x'
- öppet för exklusiv skapelse, kommer att höjaFileExistsError
om filen redan finns -
'xb'
- öppet för exklusivt'xb'
för skapande i binär. Samma somx
förutom att data är binära. -
'x+'
- läs- och skrivningsläge. Liknarw+
eftersom det kommer att skapa en ny fil om filen inte finns. Annars höjerFileExistsError
. -
'xb+'
- skriv- och läsläge. Exakt samma somx+
men data är binära
x | x + | |
---|---|---|
Läsa | ✘ | ✔ |
Skriva | ✔ | ✔ |
Skapar fil | ✔ | ✔ |
Raderar fil | ✘ | ✘ |
Första position | Start | Start |
Låt en skriva din fil med öppen kod på ett mer pytoniskt sätt:
try:
with open("fname", "r") as fout:
# Work with your open file
except FileExistsError:
# Your error handling goes here
I Python 2 skulle du ha gjort något liknande
import os.path
if os.path.isfile(fname):
with open("fname", "w") as fout:
# Work with your open file
else:
# Your error handling goes here
Läsa en fil rad för rad
Det enklaste sättet att iterera över en fil rad för rad:
with open('myfile.txt', 'r') as fp:
for line in fp:
print(line)
readline()
möjliggör mer granulär kontroll över linje-för-linje-iteration. Exemplet nedan motsvarar exemplet ovan:
with open('myfile.txt', 'r') as fp:
while True:
cur_line = fp.readline()
# If the result is an empty string
if cur_line == '':
# We have reached the end of the file
break
print(cur_line)
Att använda för-loop-iteratorn och readline () tillsammans anses vara dålig praxis.
Mer vanligtvis används readlines()
för att lagra en iterable samling av filens linjer:
with open("myfile.txt", "r") as fp:
lines = fp.readlines()
for i in range(len(lines)):
print("Line " + str(i) + ": " + line)
Detta skulle skriva ut följande:
Rad 0: hej
Rad 1: världen
Få hela innehållet i en fil
Den föredragna metoden för fil i / o är att använda with
nyckelordet. Detta säkerställer att filhandtaget stängs när läsningen eller skrivningen har slutförts.
with open('myfile.txt') as in_file:
content = in_file.read()
print(content)
eller, för att hantera stänga filen manuellt kan du avstå with
och helt enkelt ringa close
dig:
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()
Tänk på att utan att använda ett with
uttalande kan du av misstag hålla filen öppen i händelse av att ett oväntat undantag skulle uppstå så:
in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close() # This will never be called
Skriva till en fil
with open('myfile.txt', 'w') as f:
f.write("Line 1")
f.write("Line 2")
f.write("Line 3")
f.write("Line 4")
Om du öppnar myfile.txt
ser du att innehållet är:
Line 1Line 2Line 3Line 4
Python lägger inte automatiskt till rader, du måste göra det manuellt:
with open('myfile.txt', 'w') as f:
f.write("Line 1\n")
f.write("Line 2\n")
f.write("Line 3\n")
f.write("Line 4\n")
Linje 1
Linje 2
Rad 3
Rad 4
Använd inte os.linesep
som os.linesep
när du skriver filer som öppnas i textläge (standard); använd \n
istället.
Om du vill ange en kodning lägger du bara till encoding
till den open
funktionen:
with open('my_file.txt', 'w', encoding='utf-8') as f:
f.write('utf-8 text')
Det är också möjligt att använda utskriften för att skriva till en fil. Mekaniken är olika i Python 2 vs Python 3, men konceptet är detsamma i det att du kan ta utdata som skulle ha gått till skärmen och skicka den till en fil istället.
with open('fred.txt', 'w') as outfile:
s = "I'm Not Dead Yet!"
print(s) # writes to stdout
print(s, file = outfile) # writes to outfile
#Note: it is possible to specify the file parameter AND write to the screen
#by making sure file ends up with a None value either directly or via a variable
myfile = None
print(s, file = myfile) # writes to stdout
print(s, file = None) # writes to stdout
I Python 2 skulle du ha gjort något liknande
outfile = open('fred.txt', 'w')
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >> outfile, s # writes to outfile
Till skillnad från att använda skrivfunktionen lägger skrivfunktionen automatiskt till rader.
Kopiera innehållet i en fil till en annan fil
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
- Med hjälp av
shutil
modulen:
import shutil
shutil.copyfile(src, dst)
Kontrollera om det finns en fil eller sökväg
Använd EAFP- kodningsstilen och try
att öppna den.
import errno
try:
with open(path) as f:
# File exists
except IOError as e:
# Raise the exception if it is not ENOENT (No such file or directory)
if e.errno != errno.ENOENT:
raise
# No such file or directory
Detta kommer också att undvika rasförhållanden om en annan process raderade filen mellan kontrollen och när den används. Detta tävlingsförhållande kan inträffa i följande fall:
Använda
os
modulen:import os os.path.isfile('/path/to/some/file.txt')
Med hjälp av
pathlib
:import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ...
För att kontrollera om en given sökväg existerar eller inte, kan du följa ovanstående EAFP-procedur eller uttryckligen kontrollera sökvägen:
import os
path = "/home/myFiles/directory1"
if os.path.exists(path):
## Do stuff
Kopiera ett katalogträd
import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)
Destinationskatalogen får inte redan existera .
Iterera filer (rekursivt)
För att uppdatera alla filer, inklusive i underkataloger, använd os.walk:
import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename
root_dir kan vara "." för att starta från den aktuella katalogen, eller någon annan väg att börja från.
Om du också vill få information om filen kan du använda den mer effektiva metoden os.scandir så:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
Läs en fil mellan en rad rader
Så låt oss anta att du bara vill iterera mellan vissa specifika rader i en fil
Du kan använda itertools
för det
import itertools with open('myfile.txt', 'r') as f: for line in itertools.islice(f, 12, 30): # do something here
Detta kommer att läsa igenom raderna 13 till 20 som vid pythonindexing börjar från 0. Så rad nummer 1 indexeras som 0
Som också kan läsa några extra rader genom att använda next()
nyckelord här.
Och när du använder filobjektet som en iterable, använd inte readline()
här eftersom de två teknikerna för att korsa en fil inte ska blandas ihop
Slumpmässig filåtkomst med mmap
Med hjälp av mmap
modulen kan användaren slumpmässigt komma åt platser i en fil genom att mappa filen till minnet. Detta är ett alternativ till att använda vanliga filoperationer.
import mmap
with open('filename.ext', 'r') as fd:
# 0: map the whole file
mm = mmap.mmap(fd.fileno(), 0)
# print characters at indices 5 through 10
print mm[5:10]
# print the line starting from mm's current position
print mm.readline()
# write a character to the 5th index
mm[5] = 'a'
# return mm's position to the beginning of the file
mm.seek(0)
# close the mmap object
mm.close()
Byta ut text i en fil
import fileinput
replacements = {'Search1': 'Replace1',
'Search2': 'Replace2'}
for line in fileinput.input('filename.txt', inplace=True):
for search_for in replacements:
replace_with = replacements[search_for]
line = line.replace(search_for, replace_with)
print(line, end='')
Kontrollera om en fil är tom
>>> import os
>>> os.stat(path_to_file).st_size == 0
eller
>>> import os
>>> os.path.getsize(path_to_file) > 0
Båda kommer dock att kasta ett undantag om filen inte finns. Så här undviker du att behöva fånga ett sådant fel:
import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
vilket kommer att returnera ett bool
.