آموزش پایتون کلید ورود به دنیای هوش مصنوعی (گام دوم - قسمت هجدهم:کار با فایلها)

سلام رفقا

در یک سری آموزش به آموزش پایتون برای ورود به دنیای هوش مصنوعی پرداختیم. اگه تازه قرار پایتون یاد بگیرید به این لینک برید و از جلسه اول شروع کنید و گام به گام بیاین جلو. در قسمت قبلی آموزش پایتون در رابطه با توابع صحبت کردیم در این قسمت می ریم سراغ کارکردن با فایل ها.

الان ما اینجا هستیم :

تو این جلسه از آموزش پایتون میخوایم راجع به فایل ها صحبت کنیم.

هر برنامه ورودی هایی را دریافت می کنه و پس از انجام محاسبات و پردازش هایی، خروجی را بر روی نمایشگر نشون می ده و یا درون یک فایل و یا درون پایگاه داده ذخیره می کنه. همچنین چندین روش برای دریافت ورودی وجود داره. برنامه می تونه از طریق خط فرمان یا واسط های گرافیکی ورودی بگیره و یا اینکه از درون یک فایل ورودی رو بخونه.

فایل واحد منطقی ذخیره سازی داده ها بر روی دیسک است که توسط سیستم عامل مدیریت و نگهداری می شوند. سیستم فایل (File System) واحدی از (هسته) سیستم عامل است که وظیفه نگهداری، مدیریت، دسترسی و تغییرات فایل ها را بر عهده دارد.

فایل ها انواع مختلفی دارند ولی می توان آنها را به دو دسته فایل های متنی (Text Files) و فایل های باینری (Binary Files) دسته بندی کرد.

فایل های متنی که هر فرمتی را شامل می شوند. این فایل ها می توانند فایل های متنی، فایل های دودویی، فایل های HTML و فایل های با فرمت XML یا فایل های با فرمت CSV باشند.

برای خواندن از فایل یا نوشتن بر روی فایل، باید در ابتدا آن فایل را باز (Open) کنیم. در پایتون برای این کار از تابع درونی ()open استفاده می کنیم. این تابع دو آرگومان ورودی دریافت می کند، آرگومان اول مسیر و نام فایل و آرگومان دوم حالتی (Mode) است که فایل برای آن باز خواهد شد.


حالت های(mode) فایل

  • حالت خواندن ' r ' - به طور پیش فرض. این امکان را به شما می ده که فقط فایل رو بخونید ، نه آن را اصلاح کنید. هنگام استفاده از این حالت ، فایل باید وجود داشته باشه.
  • حالت نوشتن ' w ' - اگر فایلی وجود نداشته باشد ، فایل جدیدی ایجاد می کند ، در غیر این صورت داده های قبلی را به طور کامل پاک کرده و یک فایل جدید را ایجاد می کند.
  • حالت اضافه کردن ' a ' - فایلی را برای ضمیمه باز می کنه. در صورت وجود فایل ، نشانگر فایل در انتهای فایل قرار داره. یعنی فایل در حالت append است. اگر فایل وجود نداشته باشد ، فایل جدیدی را برای نوشتن ایجاد می کند.
  • حالت خواندن به صورت باینری ' rb ' - فایلی را برای خواندن فقط با فرمت باینری باز می کند. نشانگر فایل در ابتدای فایل قرار می گیرد. این حالت پیش فرض است.
  • حالت خواندن و حالت نوشتن هم زمان ' +r ' - این حالت به شما این امکان رو می ده بدون نیاز به استفاده از r و w ، همزمان فایل ها را بخونید و بنویسید.
  • خواندن و نوشتن در حالت باینری ' +rb ' - همان +r فقط در فرمت باینری.
  • حالت نوشتن به صورت باینری ' wb ' - فایلی را برای نوشتن فقط با فرمت باینری باز می کند. در صورت وجود فایل ، فایل را مرور می کند. اگر فایل وجود نداشته باشد ، فایل جدیدی برای نوشتن ایجاد کنید.
  • حالت نوشتن و خواندن ' +w ' - فایلی رو برای نوشتن و خواندن باز می کنه. رونویسی فایل های موجود در صورتی که فایل وجود داشته باشه. اگر فایل وجود نداشته باشه ، فایل جدیدی رو برای خواندن و نوشتن ایجاد می کنه.
  • حالت نوشتن و خواندن در حالت باینری ' +wb ' - یک فایل برای نوشتن و خواندن در قالب باینری باز می کنه. رونویسی فایل های موجود در صورتی که فایل وجود داشته باشه. اگر فایل وجود نداشته باشه ، فایل جدیدی رو برای خواندن و نوشتن ایجاد می کنه.
  • اضافه کردن در حالت باینری ' ab ' - همان a فقط در فرمت باینری.
  • حالت اضافه کردن و خواندن ' +a ' - مشابه +w . فایلی رو برای ضمیمه و خواندن باز می کنه. در صورت وجود فایل ، نشانگر فایل در انتهای فایل قرار دارد. فایل در حالت append باز می شه. اگر فایل وجود نداشته باشه ، فایل جدیدی را برای خواندن و نوشتن ایجاد می کنه.
  • حالت اضافه کردن و خواندن به صورت باینری ' +ab ' - همان +a فقط در فرمت باینری.
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)

پایتون 3 ، حالت جدیدی را برای ایجاد انحصاری اضافه کرد:

  • حالت ' x ' - فایلی رو برای ایجاد انحصاری باز می کنه ، اگر فایل از قبل موجود باشد FileExistsError رو برمی گردونه.
  • حالت ' xb ' - همان x فقط در فرمت باینری.
  • حالت ' +x ' - حالت خواندن و نوشتن. اگر فایل وجود نداشته باشد ، فایل جدیدی ایجاد خواهد کرد. در غیر این صورت، FileExistsError رو برمی گردونه.
  • حالت ' +xb ' - همان +x فقط در فرمت باینری.

Python 3.x Version ≥ 3.3

try:
       with open(&quotfname&quot, &quotr&quot) as fout:
              # Work with your open file
       except FileExistsError:
              # Your error handling goes here

Python 2.x Version ≥ 2.0

import os.path
if os.path.isfile(fname):
       with open(&quotfname&quot, &quotw&quot) as fout:
              # Work with your open file
else:
        # Your error handling goes here

خواندن خط به خط یک فایل

ساده ترین راه برای پیمایش خط به خط روی یک فایل:

with open('myfile.txt', 'r') as fp:
       for line in fp:
              print(line)

متد ()readline: این تابع در هر بار صدا زده شدن روی فایل، یک خط از فایل را به ما بر میگرداند. مثال زیر معادل مثال فوق است:

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)

به طور معمول ، از متد ()readlines برای ذخیره مجموعه ای قابل تکرار از خطوط فایل استفاده میشه:

with open(&quotmyfile.txt&quot, &quotr&quot) as fp:
       lines = fp.readlines()
for i in range(len(lines)):
       print(&quotLine &quot + str(i) + &quot: &quot + line)

موارد زیر رو پرینت میکنه:

Line 0: hello
Line 1: world

فایل های تکرار Iterate (به صورت بازگشتی)

برای تکرار همه فایل ها ، از جمله در زیرشاخه ها ، از os.walk استفاده کنید:

import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename

Python 3.x Version ≥ 3.5

اگر شما همچنین می خواهید اطلاعات مربوط به فایل را بدست آورید ، می توانید از روش کارآمدتر os.scandir مانند این استفاده کنید:

for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)

دریافت محتوای کامل یک پرونده

روش ارجح فایل i/o استفاده از کلمه کلیدی است. این کار اطمینان حاصل می کند که فایل پس از اتمام خواندن یا نوشتن بسته می شود:

with open('myfile.txt') as in_file:
content = in_file.read()
print(content)

یا برای بستن فایل به صورت دستی ، می توانید به سادگی close را صدا بزنید:

in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()

نوشتن در یک فایل

with open('myfile.txt', 'w') as f:
f.write(&quotLine 1&quot)
f.write(&quotLine 2&quot)
f.write(&quotLine 3&quot)
f.write(&quotLine 4&quot)

اگر myfile.txt را باز کنید ، خواهید دید که محتوای آن عبارتند از:

Line 1 Line 2 Line 3 Line 4

پایتون به طور خودکار line break رو اضافه نمی کنه ، شما باید این کار رو بصورت دستی انجام بدید:

with open('myfile.txt', 'w') as f:
f.write(&quotLine 1\n&quot)
f.write(&quotLine 2\n&quot)
f.write(&quotLine 3\n&quot)
f.write(&quotLine 4\n&quot)

Line 1
Line 2
Line 3
Line 4

هنگام نوشتن فایل های باز شده در حالت متن (پیش فرض) از os.linesep به عنوان یک پایان دهنده خط استفاده نکنید. در عوض از n\ استفاده کنید. اگر می خواهید encoding را مشخص کنید ، به سادگی پارامتر encoding را به تابع باز اضافه می کنید:

with open('my_file.txt', 'w', encoding='utf-8') as f:
f.write('utf-8 text')

همچنین می توان از دستور چاپ برای نوشتن در یک فایل استفاده کرد. مکانیزم پایتون 2 با پایتون 3 متفاوت است ، اما مفهوم همان است که شما می توانید خروجی رو که به صفحه رفته بگیرید و به جای آن به یک فایل ارسال کنید.

Python 3.x Version ≥ 3.0

with open('fred.txt', 'w') as outfile:
s = &quotI'm Not Dead Yet!&quot
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

در پایتون 2 هم می تونستید کاری از این دست انجام بدید:

Python 2.x Version ≥ 2.0

outfile = open('fred.txt', 'w')
s = &quotI'm Not Dead Yet!&quot
print s   # writes to stdout
print >> outfile, s   # writes to outfile

بر خلاف استفاده از تابع write ، عملکرد print به طور خودکار line break را اضافه می کند:

بررسی کنید که فایل یا path وجود دارد یا خیر

از سبک رمزگذاری EAFP استفاده کنید و سعی کنید آن را باز کنید.

import errno
try:
with open(path) as f:
# فایل وجود داره
except IOError as e:
# (نباشد (این چنین فایل و یا دایرکتوری وجود نداشته باشد ENOENT استثناء را مطرح کنید اگر
if e.errno != errno.ENOENT:
raise
# این چنین فایل و یا دایرکتوری وجود ندارد

اگر روند دیگری فایل رو بین چک و زمان استفاده از آن حذف کنه ، از race-conditions نیز جلوگیری می شود. این شرایط مسابقه می تواند در موارد زیر اتفاق بیفتد:

  • با استفاده از ماژول os:
import os
os.path.isfile('/path/to/some/file.txt')

Python 3.x Version ≥ 3.4

  • با استفاده از pathlib:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
       ...

برای بررسی اینکه مسیر مشخصی وجود دارد یا خیر ، می توانید روش EAFP فوق را دنبال کنید ، یا مستقیما مسیر را بررسی کنید:

import os
path = &quot/home/myFiles/directory1&quot
if os.path.exists(path):
## Do stuff

تابع os.path.exists وجود فایل یا دایرکتوری را بررسی می کند.

دسترسی به پرونده تصادفی با استفاده از mmap

با استفاده از ماژول mmap به کاربر این امکان داده میشه تا با نقشه کردن فایل به حافظه ، به طور تصادفی به مکانهای موجود در یک فایل دسترسی پیدا کند. این یک جایگزین برای استفاده از عملیات فایل عادی است.

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

جایگزینی متن در یک فایل

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

بررسی خالی بودن فایل

>>> import os
>>> os.stat(path_to_file).st_size == 0

یا

>>> import os
>>> os.path.getsize(path_to_file) > 0

با این وجود ، اگر فایل وجود نداشته باشه ، هر دو، یک خطا را می دهند. برای جلوگیری از گرفتن چنین خطایی، این کار رو انجام بدید:

import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0

که یک مقدار bool را برمی گرداند.

خواندن یک فایل بین محدوده ای از خطوط

بنابراین فرض کنید شما می خواهید فقط بین برخی از خطوط خاص یک فایل رو تکرار کنید:

برای این کار می توانید از itertools استفاده کنید:

import itertools
with open('myfile.txt', 'r') as f:
for line in itertools.islice(f, 12, 30):
# do something here

خطوط بین اندیس 13 تا 20 خوانده می شود ، همانطور که می دونید اندیس در پایتون از 0 شروع می شود. بنابراین خط شماره 1 به عنوان اندیس 0 می شود. همچنین می توانید با استفاده از کلید واژه ()next در اینجا چند خط اضافی را نیز مطالعه کنید.

و هنگامی که شما از فایل آبجکت به عنوان تکرار شونده استفاده می کنید ، لطفاً از عبارت ()readline در اینجا استفاده نکنید ، زیرا دو روش برای مرور یک فایل با یکدیگر ترکیب نمی شوند.

کپی یک درخت دایرکتوری directory tree

import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)

دایرکتوری مقصد از قبل وجود ندارد.

کپی کردن محتویات یک فایل در فایل دیگر

with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
  • با استفاده از ماژول shutil
import shutil
shutil.copyfile(src, dst)