فصل پنجم

ورودی و خروجی

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

قالب بندی دلخواه خروجی

تاکنون ما با ۲راه چاپ مقادیر آشنا شدیم : استفاده از عبارات بیانی و تابع  print ( یک راه سوم استفاده از متد ایتم های فایل     write  هست فایل خروجی استاندارد می تواند همانند   sys.stdout   رجوع داده بشود)

اغلب اوقات شما می خواهید کنترل بیشتری روی سراسر قالب بندی خروجی تون داشته باشید . ۲ راه برای قالب بندی خروجی تون وجود دارد  نخستین راه این هستش که تمام به کار گیری رشته را خودتون انجام بدهید با برش رشته و  عمل افزدون ، شما می توانید تمام قالب بندیی را که تصور ش را می کنید درست کنید. ماژول استاندارد   string  شامل برخی از عملکرد های مفید برای لایه گذاری رشته هاست. دومین راه استفاده از متد  str.format  است.

یک سوال باقی می ماند : چطوری مقادیر را به رشته ( استرینگ ) تبدیل کنیم؟ خوشبختانه پایتون راه هایی را برای تبدیل تمام مقادیر به یک رشته تدارک دیده است : مقادیر را درون توابع  repr() یا    str()   بگذارید.

 تابع   str به این صورت است که آیتمی از مقادیر را بر می گرداند که  به خوانایی دست خط انسان هستند و بصورت یک رشته قایل خواندن هستند در حالیکه repr به معنی تولید کردن آیتمی است که به وسیله مفسر خوانده می شود. آیتم هایی که بوسیله مفسر خوانده می شوند ممکن است شامل برخی کاراکترهای خاص مثل کاراکتر خظ جدید یا new line  باشند که برای انسان قایل خوانایی ندارند. برای آیتم هایی که تمثیل خواصی برای انسان ندارند str مقدار مشابه ای همچون repr بر می گرداند. تعداد زیادی از مقادیر ،مثل اعداد و ساختمان هایی از قبیل لیست و دیکشنری، تمثیل مشابهی در استفاده از هر دو تابع دارند.رشته ها و اعداد ممیز شناور ( اعشاری ) در جاهای به خصوصی ، تمثیل های مجزایی دارند.

مثال :

>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(0.1)
'۰٫۱'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print(s)
The value of x is 32.5, and y is 40000...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
>>> آرگومان repr() می تواند تمام اشیای پایتون باشد#
... repr((x, y, ('iraj', '1988')))
"(۳۲٫۵, ۴۰۰۰۰, ('iraj', '1988'))"

مثالی  از کاراکتر خط جدید یا نیو لاین که فقط برای مفسر پایتون مفهوم داره و برای انسان خوانا نیست:

>>> print 'welcome to \n python'
welcome to 
 python

>>> a='hello \n   world'
>>> str(a)
'hello \n world'
>>> repr(a)
"'hello \\n world'" 
>>> print a
hello 
   world

اینجا ۲ راه برای نوشتن جدولی از مربعات  و مکعبات اعداد داریم :

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3)) ,
...     توجه کنید که کاربرد end برای ادامه ی خط پیشین است یعنی پرینت بعدی ادامه پرینت اولی چاپ می شود#
...     print(repr(x*x*x).rjust(4))
...
 ۱   ۱    ۱
 ۲   ۴    ۸
 ۳   ۹   ۲۷
 ۴  ۱۶   ۶۴
 ۵  ۲۵  ۱۲۵
 ۶  ۳۶  ۲۱۶
 ۷  ۴۹  ۳۴۳
 ۸  ۶۴  ۵۱۲
 ۹  ۸۱  ۷۲۹
۱۰ ۱۰۰ ۱۰۰۰

>>> for x in range(1, 11):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
 ۱   ۱    ۱
 ۲   ۴    ۸
 ۳   ۹   ۲۷
 ۴  ۱۶   ۶۴
 ۵  ۲۵  ۱۲۵
 ۶  ۳۶  ۲۱۶
 ۷  ۴۹  ۳۴۳
 ۸  ۶۴  ۵۱۲
 ۹  ۸۱  ۷۲۹
۱۰ ۱۰۰ ۱۰۰۰

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

 

این مثال متد رشته، rjust  را شرح می دهد این متد به سمت چپ رشته فضای خالی اضافه می کند .متد های center و ljust هم تقریبا شبیه هسنتد. متد center از دو طرف فضا را اضافه میکند اما متد ljust فقط از راست عمل می کند. اگر طول رشته بیش از حد طولانی بود( طول رشته بزرگتر از n باشد ) رشته بریده نمی شود و بدون تغییر چاپ می شود.برای مثال :

>>> 'i love python :)'.center(50)
' i love python 🙂 '
>>> 'i love python :)'.ljust(20)
'i love python 🙂 '

>>> 'i love python :)'.rjust(20)
' i love python :)'

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

>>> ‘ i r a n ‘ . l j u s t ( 2 ) [ : 2 ]              #  رشته ی ایران را از کاراکتر اول تا دوم بخش می کند ( ایندکس کاراکتر ها از ۰ شروع می شود )
‘ i r ‘

 

متد دیگری وجود دارد به نام    zfill()  ، که با افزودن صفر به سمت چپ رشته های عددی کار می کند. این متد علامت های مثبت و منفی را نیز درک می کند :

>>> '12'.zfill(5)
'۰۰۰۱۲'
>>> '-3.14'.zfill(7)
'-۰۰۳٫۱۴'
>>> '3.14159265359'.zfill(5)
'۳٫۱۴۱۵۹۲۶۵۳۵۹'

 کار برد اساسی متد str.format()  ، خوب به مثال زیر دقت کنید :

>>> print('We are the {0} who say "{1}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"

 به جای براکت ها و کاراکتر های داخل آنها ( فیلد های فرمت را فراخوانی می کنند) ، اشیای گذاشته شده درون متد فرمت ، قرار گذاشته می شود. عدد داخل براکت ها به موقعیت ایتم گذاشته شده در متد فرمت اشاره می کند .

>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs')) # جای شماره ها عوض شده است
eggs and spam

اگر از آرگومان های کلیدی در متد فرمت استفاده شده باشد ، مقادیر آنها به وسیله اسم آرگومان، ارجاع داده می شود:

>>> print('This {food} is {adjective}.'.format(
...       food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

 آرگومان های وابسته به موقعییت و آرگومان  های کلیدی به طور دلخواه می توانند باهم ترکیب بشوند :

>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
                                                       other='Georg'))
The story of Bill, Manfred, and Georg.

 

“:” اختیاری ای که در فیلد نام قرار می دهیم می توانیم کنترل بیشتری داشته باشیم که چگونه مقدار را فرمت دهی کنیم. مثال زیر نشان می دهد که چگونه عدد پی را تا ۳ نقطه اعشار کوتاه می کنیم:

>>> import math
>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))
The value of PI is approximately 3.142.

نکته : n f.  یعنی به تعداد n بعد از اعشار گرد کن ( f یعنی float _عدد اعشاری_ )

 

گذاشتن یک عدد صحیح بعد از ( : ) سبب میشود تا فیلد به اندازه ی کمترین مقدار اندازه ی کاراکتر تنظیم بشود. این کار باعث زیباتر شدن جدول می شود :

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, phone))
...
Jack       ==>       4098
Dcab       ==>       7678
Sjoerd     ==>       4127

 نکته :  ۱۰d یعنی قبل از عدد صحیحی که به عنوان آرگومان متد فرمت است به اندازه   ۱۰ تا فضای خالی قرار بده _ در اینجا phone ( مقدار کلید درون دیکشنری ) عدد صحیح است

اگر یک متن طولانی دارید که لازم است قالب بندی شود نیازی نیست متن را تکه تکه کنید زیباتر هستش اگر شما یتوانید متغیرها رو بجای قالب بندی توسط موقعیت ، بوسیله نامشون  فرمت بندی کنید. این کار در زیر با استفاده از یک دیکشنری و دسترسی به کلید های توسط جفت براکت های “[]” برای دسترسی به کلید ها صورت گرفته است:

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; ' # ساده است دقت کنید
          'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

همچنین می توانید این کار را به وسیله گذاشتن دیکشنری با علامت ( ** )  همچون آرگومان های کلیدی ، انجام بدهید.:

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

این هم یک تابع جدید _  vars()  _  که خیلی مفیده و کارش اینه که یک دیکشنری شامل تمام متغییر های تعریف شده در یک ناحیه مثل درون تابع یا کلاس و یا ..  را  به همراه مقادیرشان بر می گرداند

>>> def f():
	a='iraj'
	b='dotpy.ir'
	c='python programming'
	print vars()

>>> f()
{'a': 'iraj', 'c': 'python programming', 'b': 'dotpy.ir'}

قالب بندی سنتی رشته

عملگر % نیز می تواند برای قالب بندی رشته ها مورد استفاده قرار بگیرد. به صورت زیر:

>>> import math
>>> print('The value of PI is approximately %5.3f.' % math.pi)
The value of PI is approximately 3.142.
>>> print('Hello mr %5' % 'iraj jelodari')
Hello mr iraj jelodari

چونکه  str.format() کاملا جدید و تازه است هنوز کدهای پاتون خیلی زیادی از عملگر % استفاده می کنند .با این حال روش سنتی از زبان پایتون حذف خواهد شد و این str.format()  است که کاربدش تضمین شده است

خواندن و نوشتن فایل ها

( ) open  یک آیتم فایل را بر می گرداند، و  اکثر اوقات با ۲ آرگومان به کار می رود: (open(filename, mode.

>>> f = open('./workfile', 'w')

آرگومان  اول یک رشته شامل اسم فایل است. آرگومان دوم یک رشته دیگه شامل کاراکتر های کم تعدادی است که راهی را که فایل استفاده می شود، را شرح می دهد. حالت  r  ”  وقتی که فایل فقط خوانده می شود، ” w ”  برای فقط نوشتن فایل است ( وفایل با نام مشابه محتویاتش حذف می شه و دوباره نوشته می شود ) و ” a ” فایل را برای افزودن باز می کند، تمام اطلاعاتی که توی فایل نوشته می شوند به صورت  اتوماتیک به آخر فایل افزوده می شوند.    ” +r ”  فایل را برای هر دو عمل خواندن و نوشتن باز می کند. آرگومان مد ( آرگومان دومی ) اختیاری است و اگر نادیده گرفته شود ، ” r ”  در نظر گرفته می شود.

معمولا، فایل ها به صورت متنی باز می شوند ، به این معنی که رشته هایی را هم داخل فایل می توانید بنویسید و هم می توانید از داخل فایل بخوانید،رشته هایی که با یک کد مخصوص ( رمز- encoding ) رمز گذاری ( encode ) شده اند (  حالت پیشفرض UTF-8 است ). ” b ”  مد باز کردن فایل های دودویی ( باینری ) را اضافه می کند که باعث می شود هم داخل این فایل بنویسیم و هم از داخل این فایل ها بخوانیم. این مد برای تمام فایل های غیر متنی باید مورد استفاده قرار بگیرد.

 

متد های آیتم های فایل

در بقیه مثال های این فصل فرض می شود که شی فایل که  f نامیده می شود از قبل معرفی شده است.

برای خواندن محتویات فایل ها  read فرا خوانده می شود که مقداری از داده ها را می خواند و بصورت بک رشته یا بیت هایی از یک شی بر می گرداند. سایز یک آرگومان عددی دلخواه است . وقتی که سایز منفی یا اصلا نوشته نشود کل محتویات فایل خوانده می شود و برگردانده می شود. اگر پایان فایل فرا رسیده باشد f.read()  یک رشته خالی را بر می گرداند.

>>> f.read()
'This is the entire file.\n'
>>> f.read()
''

f.readline() یک خط از فایل را می خواند، کاراکتر خط جدید  (\n) در آخر رشته گذاشته می شود و در صورتی این کاراکتر رو نمی بینیم که دیگر به خط اخر فایل رسیده ایم چونکه دیگر خط جدیدی نیست که بخواهد آغاز بشود. اگر که این متد هم یک رشته خالی را بر گرداند معنیش این است باز به اخر فایل رسیده ایم. اگر خطی خالی باشد فقط کاراکتر خط جدید /n باز گردانده خواهد شد

>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''

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

 

>>> f.readlines()
['This is the first line of the file.\n', 'Second line of the file\n']

یک گزینه مناسب برای خواندن فایل ها استفاده از حلقه هستش. این  هم در میزان استفاده از مموری تاثیر گذار هستش و هم اینکه سریع تره و کد سبکی هم داره:

>>> for line in f:
...     print(line, end='')
...
This is the first line of the file.
Second line of the file

f.write(string)  یک رشته  رو توی فایل می نویسد و تعداد کاراکتر های آن را می گرداند:

>>> f.write('This is a test\n')
۱۵

برای نوشتن آیتمی که نوعش رشته نباشد باید اول ان را به رشته تبدیل کنیم :

>>> value = ('the answer', 42)
>>> s = str(value)
>>> f.write(s)
۱۸

f.tell()  یک عدد صحیح را صحیح را بر می گرداند که موقعیت جاری شی فایل  درون فایل  را نشان می دهد.  بیت ها از آغاز فایل شمرده می شوند. بمنظور تغیر موقعیت درون فایل  از f.seek(offset, from_what) استفاده می کنیم. موقعیت از افزوده شدن offset  به نقطه ارجاع محاسبه می شود. نقطه ارجاع بوسیله آرگومان from_what مشخص می شود. اگر from_what  صفر باشد موقعیت اول فایل قرار دارد. ۱ برای موقعیت جاری فایل مورد استفاده قرار می گیرد. ۲ به آخر فایل اشاره می کند. اگر from_what  رو اصلا ننویسیم و جاش بذاریم همان صفر و آغاز فایل در نظر گرفته می شود.

>>> f = open('/tmp/workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
۱۶
>>> f.seek(5)     # Go to the 6th byte in the file
۵
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # به سه بیت ماقبل آخر فایل اشاره می کند
۱۳
>>> f.read(1)
b'd'

وقتی شما یک فایل را ایجاد می کنید f.close()  آن را می بندد و منابع سیستمی را که با open  فایل گرفته شده را آزاد می کند. پس از بستن فایل تلاش برای استفاده کردن از شی فایل با شکست مواجه می شود.

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file

تمرین خوبیه که از کلید واژه ی  with  برای سرکار داشتن با شی فایل استفاده کنید. سودی که داره اینه که اگر فایل احتمالا بسته بود مشکلی پیش نمیاد ، حتی اگر استثنایی پیش بیاد . همچنین این روش کوتاه تر از بلاک try-finally هستش. ( استثنا ها در فصل شش بطور مفصل شرح خواهند داده شد)

>>> with open('/tmp/workfile', 'r') as f:
...     read_data = f.read()
>>> f.closed
True

شی فایل متدهایی دیگر از قبیل isatty()  و truncate()  نیز دارد که کمتر مود استفاده قرار می گیرند . برای اطلاعات بیشتر به بخش Library Reference  از مستندات پایتون رجوع کنید.

5 دیدگاه برای «فصل پنجم»

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *