PythonGuide/InputOutput

من PFWiki

اذهب إلى: تصفح, البحث

محتويات

التعامل مع الملفات

هنتكلم فى الفصل دا عن التعامل مع ال files وتحديدا ال IO اختصارا ل Input/Output ال file type بيعبر عن صف مسئول عن التعامل مع الملفات (ممكن يكون سوكيت او غيره بما ان كل شئ عبارة عن file)

فى اكثر من طريقة لإنشاء file object ودا عن طريق open او file class open هتعمل ريترن بfile object وهى معرفة كالتالى open(name, mode, buffering)

حيث name هو مسار الملف mode هو بيعبر عن حالة الوصول (الملف مفتوح للقراءة ، للكتابة ، للإضافة ؟) الإفتراضى هو r للقراءة

r → قراءة فقط w → كتابة فقط (بيتم محو كل البيانات الموجودة) a → للإضافة من عند النهاية ،مع عدم محو البيانات r+ → قراءة وكتابة w+ → كتابة وقراءة اى من ال modes السابقة اذا لحقته ب b اختصارا ل binary سيتم التعامل مع binary read, binary write, .. etc

ال buffering لتحديد هل سيتم عمل اى buffering فى حال التعامل مع الملف، الإفتراضى هو -1 (بيتم النقل لنظام التشغيل)

.close()

لغلق ال file object

.read(num=None)

بتقوم بقراءة عدد معين من البايتات وفى حال عدم تحديده بيتم قراءة الملف بكامله

.readline()

قراءة سطر واحد

.readlines()

قراءة كل السطور (على صورة list)

.tell()

بتخبرنا بالمكان الحالى

.fseek(offset, whence=0)

بتنقل المكان الحالى الى offset معين بعد ال whence whence ربما تكون 0 (اى بداية الملف ) او1 (المكان الحالى) او 2 (نهاية الملف) عندنا ملف سميناه iotest.xcd فيه التالى 0123456789

.write(s)

يقوم بكتابة s فى الملف

.writelines(seq_of_strings)

يقوم بكتابه كل عناصر seq_of_strings فى الملف --كقيامك بإستدعاء write على كل عنصر فى هذه ال sequence

.fileno()

الحصول على File Descriptor خاص بال file

.flush()

لتأكيد نقل الbuffer الداخلى كله على الملف

.name

للحصول على مسار الملف

.mode

للحصول على ال access mode

.encoding

للحصول على الإنكودينج

.closed

للتحقق من تحقق اغلاق المسار

FNAME="iotest.xcd"
txt="""
line 1
line 2
line 3
line 4
line 5
line 6
line 7
some text
yada yada yada!
"""
f=open(FNAME, "w")
print f.fileno()
print f.name
print f.mode
print f.closed
f.write(txt)
f.close()
print f.closed

فى المثال السابق قمنا بفتح ملف iotext.xcd للكتابة، وكتبنا فى داخله محتويات المتغير txt الناتج

3
iotest.xcd
w
False
True


القراءة

f=open(FNAME, "r")
lines=f.readlines()
for line in lines:
    print "LINE = > ", line, #avoid printing a new line.
الناتج
LINE = >  
LINE = >  line 1
LINE = >  line 2
LINE = >  line 3
LINE = >  line 4
LINE = >  line 5
LINE = >  line 6
LINE = >  line 7
LINE = >  some text
LINE = >  yada yada yada!

معاملات سطر الأوامر لبرنامجك

بكل بساطة مش هتحتاج غير ال argument vector ودى موجودة فى ال sys.argv لو فاكر int main(int argc, char** argv){

} فللوصول لل argv استخدم argv الموجودة بال sys module وللحصول على عددهم استخدم len(argv)

striky@striky-desktop:~$ python myecho.py hello world 123 "78 yay" 
Number of arguments:  5 
myecho.py 
hello 
world 
123 
78 yay


myecho.py
#!bin/python 
 
from sys import argv # arguments vector. 
 
print "Number of arguments: ", len(argv) 
 
for arg in argv: 
        print arg

More IO stuff

فى عندنا 2 modules مهمين هما os, os.path ضيفهم كالتالى

import os
import os.path as op


os.uname()

بتعيد tuple مكونة من (sysname, nodename, release, version, machine)

print os.uname()
 
#('Linux', 'striky-desktop', '2.6.24-21-generic', '#1 SMP Tue Oct 21 23:43:45 UTC 2008', 'i686')


os.getcwd()

بتعيد المسار الحالى

print os.getcwd()
 
/home/striky/workspace/pytut/src
os.getcwdu()

مثل سابقتها ولكن بتعمل ريترن ب unicode

os.environ

هى dictionary مخزن فيه متغير البيئة environment مثل ال HOME, LOGNAME, PATH,.. etc للإطلاع عليهم

for key, val in os.environ.items():
    print key, " => ", val


للحصول على مفتاح بعينه

os.getenv(key, default)

للخصول على قيمة مفتاح ما فى الenviron

print os.getenv("HOME")

ال default سيتم اعادتها فى حالة عدم وجود المفتاح

انا root ?

def isroot():
 
	return os.getenv("USER")=="root"


طبعا تقدر تستخدم ال keys, values methods الخاصة بال environ dictionary.

os.putenv(key, value)

إضافة key لل environment بقيمة value

os.unsetenv(key)

حذف key ما

os.chdir(to)

بتقوم بنقل المسار الحالى cwd الى to

print os.getcwd()
 
os.chdir("/home/striky")
print os.getcwd()
os.chdir("Music")
print os.getcwd()
 
output
/home/striky/workspace/pytut/src
/home/striky
/media/s3/Music

لاحظ ان Music هنا symbolic link تحت /home/striky وبيشير ل /media/s3/Music

os.listdir(path)

بتقوم بإعادة list من مكونات ال path

p=os.getcwd() #/home/striky/workspace/pytut/src
print os.listdir(p)
['userstringtest.py', 'iosess.py', 'gcombo.py', 'iohelpers.py', 'oopsample.py', 'iotest.xcd', 'gtk1.py', 'complpath.py']
os.link(src,dest)

بتنشئ hard link من src الى dest

os.symlink(src, dest)

بتنشئ symbolic link من src إلى dest

os.unlink(path)

حذف path

os.remove(path)

مثل os.unlink

os.rmdir(path)

لحذف مجلد معين

os.rename(src, dest)

اعادة التسمية

os.removedirs(path)

بتقوم بالحذف من اسفل لأعلى مثلا

os.removedirs('foo/bar/baz')

ستقوم بحذف مجلد baz اولا ثم bar ثم foo

chmod(path, mode)

بتقوم بتعديل ال mode على path

chown(path, uid, gid)

تحديد ال uid, gid على path معين

print os.sep # /

الفاصل العناصر المسار

/home/striky
print os.curdir #.

المجلد الحالى وهى ال ".”

print os.altsep#None

حرف فاصل بديل

print os.pardir#..

المجلد الأب وهى ال "..”

print os.extsep#.

الفاصل للإمتدادات وهو ال ".”

print os.pathsep#:

الفاصل فى متغير ال PATH وهنا:

print repr(os.linesep)#\n

الفاصل بين السطور وهنا هو ال "\n”

p=os.getcwd() #/home/striky/workspace/pytut/src
F=p+r'/'+"iohelpers.py"
print op.basename(F)
 
print op.isfile(F)
print op.islink(F)
print op.isabs(F)
print op.isdir(F)
print op.isdir(p)
print op.ismount("/media/s3")
print op.abspath(F)
print op.dirname(F)
print op.split(F)
print op.splitdrive(F)
print op.splitext(F)
print op.exists(F+"xx")#Nope!
print op.getatime(F) #last access time
print op.getmtime(F) #last modification time
print op.getsize(F)  #file size.
 
print op.join("/home", "striky", "Music")

الناتج

iohelpers.py
True
False
True
False
True
True
/home/striky/workspace/pytut/src/iohelpers.py
/home/striky/workspace/pytut/src
('/home/striky/workspace/pytut/src', 'iohelpers.py')
('', '/home/striky/workspace/pytut/src/iohelpers.py')
False
1226557143.0
1226557142.0
521
/home/striky/Music
('/home/striky/workspace/pytut/src/iohelpers', '.py')
exists(path)

هل المسار موجود ؟

isfile(path)

هل ال path ملف؟

isdir(path)

هل ال path مجلد؟

islink(path)

هل ال path عبارة عن link ؟

ismount(path)

هل هو عبارة عن نقطة ضم ؟

isabs(path)

هل هو المسار بالكامل ؟


basename(path)

القاعدة فى المسار

abspath(path)

المسار المطلق

dirname(path)

اسم المجلد


getatime(path)

الحصول على توقيت ال last access

getmtime(path)

الحصول على توقيت ال last modification

getctime(path)

الحصول على توقيت ال last change او ال last creation اذا كان على windows


getsize(path)

الحصول على مساحة path

join(a)

لدمج مكونات الpath بإستخدام الفاصل المناسب

split(path)

تقوم بإعادة tuple مكونة من ال dirname وال basename

splitdrive(path)

تقوم بإعادة tuple مكونة من ال drive, وباقى المسار

splitext(path)

تقوم بإعادة tuple مكونة من المسار كامل بدون الإمتداد و الإمتداد


File Pointer

يمكن تكون مليت من إستخدام FileHandler.write

>>>F = open(fileName, 'w')
>>>print >> F, 'Hola'  #It will write the Hola word to the file that we opened
>>>F.close()
 
>>>F=open(fileName, 'r')
>>>for line in F.readlines(): print line
Hola  #Output!


على فرض إنك هتعمل File ودا معناه إنك هتستخدم ال w' permission'

>>> f = open('C:\\2.txt', 'w') #Open 2.txt for writing mode.
>>> print >> f, 'Hola!'  #Add 'Hola' to it
>>> print >> f, 'Hello!' # same
>>> print >> f, 'Using File Pointer !' #the same
>>> f.close() #closing the file handler.
>>> f = open('C:\\2.txt', 'r')  # Open in reading mode.
>>> for line in f.readlines(): #iterates through the file lines
	print line #printing each line.
#Here is the output.	        
Hola!
 
Hello!
 
Using File Pointer !
>>>f.close() #closing the handler.

طب تمام .. هنفتح ال File مرة تانية ولكن فى ال Append mode

>>> f=open('C:\\2.txt', 'a')
>>> print >> f, 'Programming Fr34ks r0x!'
>>> print >> f, 'File pointers are',  #Note : this comma is used to avoid printing a new line.
>>> print >> f, ' so great' # added to the line 'File pointers are'
>>> f.close()


نقرا اللى مكتوب فى ال File بإننا نعمل Iteration بسيطة على ال filehandler.readlines method

>>> f=open('C:\\2.txt', 'r')
>>> for line in f.readlines():
	print line
# The output 
 
Hola!
Hello!
Using File Pointer !
Programming Fr34ks r0x!
File pointer are  so great


التعامل مع ملفات CSV و INI

ConfigParser

موديل ConfigParser لمعالجة ملفات ال .ini “لاعلاقة لها بالرجيسترى!” ملف ال .ini نوع قديم من وصف البيانات ومستخدم بكثرة فى التطبيقات القديمة نسبيا مثال

[program]
name = SVM
version = 0.2.4
license = GPLv3
 
[author]
name = Ahmed Youssef
email = guru.python@gmail.com


هنا فى الملف يوجد 2 sections او قسمين الأول program والثانى author كل منهم بيحوى keys/values “فى بيسموها اوبشنز" براحتك مثلا ال name هو key تحت ال program section وقيمته SVM احفظ الملف السابق وليكن tst.cfg

1- استدعى ال ConfigParser موديل

from ConfigParser import *

2- انشئ اوبجكت

cp=SafeConfigParser() #create an object of SafeConfigParser


لاحظ ان فى كذا كلاس RawConfigParser, ConfigParser, SafeConfigParser فال RawConfigParser هو الأب واشتقه ال ConfigParser وهو الأب ل SafeConfigParser لذا قم بإستخدامه دائما

3- قم بقراءة الملف

cp.read("tst.cfg") #read by filename.

ال configparser object اللى انشئناه cp بيقوم بقراءة الملف بإستخدام ال read method

.add_section(section)

لإضافة سكشن جديد

.set(section, key, value)

لإضافة key جديد تحت القسم section وله قيمة value

.sections()

للحصول على جميع الأقسام

.has_section(section)

هل يوجد قسم بإسم section ؟

.get(section, key)

للحصول على قيمة ل key تحت section

.options(section)

للحصول على كل الoptions تحت section معين

.has_option(section, option)

هل section يحوى option بإسم option ؟

.items(section)

الحصول على list مكونة من tuples بتشمل key, value مثلا

[('name', 'Ahmed Youssef'), ('email', 'guru.python@gmail.com')]
.write(fp)

كتابة الملف سواء على ال stdout او فى ملف ما.. الخ الخ فى مجموعة من ال Errors مثلا NoSectionError, ParsingError, DuplicateSectionError, NoOptionError ودى فى حال محاول الوصول لقسم او اختيار غير موجود او محاولة التكرار او خطأ فى معالجة الملف "كتابة بصورة غير سليمة" وغيرهم..

من الحاجات اللى تهمك.. السكاشن والoptions

    SECTCRE = re.compile(
 
        r'\['                                 # [
 
        r'(?P<header>[^]]+)'                  # very permissive!
 
        r'\]'                                 # ]
 
        )
    OPTCRE = re.compile(
 
        r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
 
        r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
 
                                              # followed by separator
 
                                              # (either : or =), followed
 
                                              # by any # space/tab
 
        r'(?P<value>.*)$'                     # everything up to eol
 
        )


تطبيق على الملف السابق

from ConfigParser import *
import sys
 
cp=SafeConfigParser() #create an object of SafeConfigParser
 
cp.read("tst.cfg") #read by filename.
 
print cp
print "Sections: ", cp.sections()
print "Options under [program]: ", cp.options("program")
print cp.items("author")
cp.add_section("links")
cp.set("links", "pf", "http://www.programming-fr34ks.net")
cp.set("links", "python", "http://www.python.org")
cp.set("author", "website", "http://ahmedyoussef.wordpress.com")
 
#print it out...
for sec in cp.sections():
    print "--%s:"%sec
    for key, value in cp.items(sec):
        print "\t", key, " = ", value
 
print "--------"
 
cp.write(sys.stdout)


الناتج

<ConfigParser.SafeConfigParser instance at 0xb7dc0f8c>
Sections:  ['program', 'author']
Options under [program]:  ['version', 'name', 'license']
[('name', 'Ahmed Youssef'), ('email', 'guru.python@gmail.com')]
--program:
	version  =  0.2.4
	name  =  SVM
	license  =  GPLv3
--links:
	python  =  http://www.python.org
	pf  =  http://www.programming-fr34ks.net
--author:
	website  =  http://ahmedyoussef.wordpress.com
	name  =  Ahmed Youssef
	email  =  guru.python@gmail.com
--------
[program]
version = 0.2.4
name = SVM
license = GPLv3
 
[links]
python = http://www.python.org
pf = http://www.programming-fr34ks.net
 
[author]
website = http://ahmedyoussef.wordpress.com
name = Ahmed Youssef
email = guru.python@gmail.com

راجع ConfigParser.py للإطلاع على المزيد

معالجة ملفات ال CSV

CSV هى اختصار ل comma separated values من الأسم واضح انها تستخدم فى تمثيل قيم مع فصلها بإستخدام الفاصلة (الcomma) فى صفوف (تستخدم عادة فى استيراد او تصدير بيانات ما ربما قاعدة بيانات مثلا؟) لاحظ ممكن يكون الفاصل مجرد مسافة او سلاش / او او او ولكن الأشهر هو ال فاصلة مثال

ahmed, 19, m 
ayman, 20, m

وقد تحتوى على صف اول يمثل الهيدر (يشمل عناوين الأعمدة)

name, age, sex
ahmed, 19, m 
ayman, 20, m


على فرض لدينا ملف بإسم somefile.csv وفيه البيانات التالية

ahmed, m, 19
wael, m, 20
radwa, f, 19
gina, f, 21
ayman, m, 20

استدعى ال csv module كالتالى

import csv

قم بإنشاء reader object “مسئول عن القراءة للملف ومعالجته" بإستخدام cvs.reader()

reader=csv.reader(open("somefile.csv", "rb")) #default dialect. #b as a catch for win32

. تقدر تستخدم ال for loop مع ال reader فهى تقوم بعمل yield لكل صف يتم قراءته وللحصول على رقم الصف استخدم ال line_num

for row in reader:
    print row, " at: ", reader.line_num

فلنقم بتحسين المثال بعض الشئ

import csv
 
f=open("somefile.csv", "rb")
try:
    reader=csv.reader(f) #default dialect. #b as a catch for win32.
 
    for row in reader:
        print row, " at: ", reader.line_num
 
 
except Exception, ex:
    print ex.message
finally:
    f.close()


اذا اردت ربط الصف بقاموس وذلك بتحديد اسماء الأعمدة كالتالى

    reader=csv.DictReader(f, fieldnames=("name", "age", "sex")) #default dialect. #b as a catch for win32.
 
    for row in reader:
        print row, " at: ", reader.line_num
        print row["name"] #the name column


للكتابة الموضوع سهل ايضا بتنشئ writer (كاتب) من csv.writer تكتب الheader (اسماء الاعمدة) بإستخدام الطريقة writer.writerow وتعمل دوارة على المدخلات لكتابة كل صف على سبيل المثال

import csv 
 
f=open("somefile1.csv", "w") 
try: 
 
    writer=csv.writer(f) 
    inputrows=( 
           (1, "ahmed", "ahmedf1@gmail.com"), 
           (2, "ayman", "aymanf2@gmail.com"), 
           (3, "smsm", "smsm@yahoo.com") 
           ) 
 
    headers=("id", "user", "email") 
    writer.writerow(headers) 
 
    for row in inputrows: 
        writer.writerow(row) 
 
except Exception, ex: 
    print ex.message 
 
finally: 
    f.close()

للمزيد حول ال CSV راجع وثائق بايثون

→ Functional Programming InputOutput Parsing HTML XML ←
أدوات شخصية