تتيح لك وحدة zipfile في بايثون التعامل بكفاءة مع ملفات ZIP، وهي صيغة قياسية لضغط البيانات وأرشفتها. باستخدام هذه الوحدة، يمكنك إنشاء ملفات ZIP وقراءتها وكتابتها واستخراجها وفهرستها.
يُعلّمك هذا الدرس كيفية التعامل مع ملفات ZIP باستخدام zipfile في بايثون، مما يُحسّن إدارة الملفات وتبادل البيانات عبر الشبكات. سيُحسّن فهم هذه المفاهيم قدرتك على العمل مع الملفات المضغوطة في بايثون، مما يُحسّن تخزين البيانات ونقلها.
للحصول على أقصى استفادة من هذا الدرس، يجب أن تعرف أساسيات العمل مع الملفات، واستخدام العبارة with، ومعالجة مسارات نظام الملفات باستخدام pathlib، والعمل مع الفئات والبرمجة الموجهة للكائنات.
البدء باستخدام ملفات ZIP
ملفات ZIP أداة معروفة وشائعة في عالمنا الرقمي اليوم. هذه الملفات شائعة الاستخدام على نطاق واسع لتبادل البيانات عبر منصات متعددة عبر شبكات الحاسوب، وخاصةً الإنترنت.
يمكنك استخدام ملفات ZIP لتجميع الملفات العادية في أرشيف واحد، وضغط بياناتك لتوفير مساحة على القرص، وتوزيع منتجاتك الرقمية، وغير ذلك الكثير. في هذا الدرس، ستتعلم كيفية التعامل مع ملفات ZIP باستخدام وحدة zipfile في بايثون.
نظرًا لأن المصطلحات المتعلقة بملفات ZIP قد تكون مربكة في بعض الأحيان، فسوف يلتزم هذا البرنامج التعليمي بالاتفاقيات التالية فيما يتعلق بالمصطلحات:
| المصطلح | المعنى |
|---|---|
| ملف ZIP، أو أرشيف ZIP، أو الأرشيف | ملف فعلي يستخدم تنسيق ملف ZIP |
| ملف | ملف كمبيوتر عادي |
| ملف العضو | ملف يشكل جزءًا من ملف ZIP موجود |
سيساعدك فهم هذه المصطلحات بوضوح على تجنب الالتباس أثناء قراءة الأقسام القادمة. أنت الآن جاهز لمواصلة تعلم كيفية التعامل مع ملفات ZIP بكفاءة باستخدام كود بايثون!
ما هو ملف ZIP؟
ربما سبق لك التعامل مع ملفات ZIP والعمل عليها. نعم، الملفات ذات الامتداد .zip منتشرة في كل مكان! ملفات ZIP، المعروفة أيضًا باسم أرشيفات ZIP، هي ملفات تستخدم صيغة ZIP.
شركة PKWARE هي الشركة التي ابتكرت هذا التنسيق وطبقته لأول مرة. وقد وضعت الشركة مواصفات التنسيق الحالية وصانتها، وهي متاحة للعامة، وتسمح بإنشاء منتجات وبرامج وعمليات تقرأ وتكتب الملفات باستخدام تنسيق ZIP.
صيغة ZIP هي صيغة تخزين ونقل ملفات متوافقة ومتعددة المنصات. تجمع بين ضغط البيانات دون فقدانها، وإدارة الملفات، وتشفيرها.
ضغط البيانات ليس شرطًا لاعتبار الأرشيف ملف ZIP. لذا، يمكنك الاحتفاظ بملفات أعضاء مضغوطة أو غير مضغوطة في أرشيفات ZIP. يدعم تنسيق ملف ZIP عدة خوارزميات ضغط، إلا أن Deflate هو الأكثر شيوعًا. كما يدعم التنسيق عمليات التحقق من سلامة المعلومات باستخدام CRC32.
على الرغم من وجود تنسيقات أرشفة أخرى مماثلة، مثل ملفات RAR وTAR، إلا أن تنسيق ملف ZIP سرعان ما أصبح معيارًا شائعًا لتخزين البيانات بكفاءة وتبادل البيانات عبر شبكات الكمبيوتر.
ملفات ZIP منتشرة في كل مكان. على سبيل المثال، تعتمد حزم برامج Office، مثل Microsoft Office وLibre Office، على صيغة ZIP كملف حاوية للمستندات. هذا يعني أن ملفات .docx و.xlsx و.pptx و.odt و.ods و.odp هي في الواقع أرشيفات ZIP تحتوي على عدة ملفات ومجلدات تُشكل كل مستند. من الملفات الشائعة الأخرى التي تستخدم صيغة ZIP ملفات jar وwar وepub.
ربما تكون على دراية بموقع GitHub، الذي يوفر استضافة ويب لتطوير البرمجيات والتحكم في الإصدارات باستخدام Git. يستخدم GitHub ملفات ZIP لتجميع مشاريع البرمجيات عند تنزيلها على جهاز الكمبيوتر المحلي.
تتيح لك ملفات ZIP تجميع الملفات وضغطها وتشفيرها في حاوية واحدة قابلة للتشغيل المتبادل والنقل. يمكنك بث ملفات ZIP وتقسيمها إلى أجزاء واستخراجها ذاتيًا، وغير ذلك الكثير.
لماذا نستخدام ملفات ZIP؟
إن معرفة كيفية إنشاء ملفات ZIP وقراءتها وكتابتها واستخراجها تُعدّ مهارةً مفيدةً للمطورين والمحترفين الذين يعملون مع أجهزة الكمبيوتر والمعلومات الرقمية. ومن بين مزاياها الأخرى، تتيح لك ملفات ZIP ما يلي:
- تقليل حجم الملفات ومتطلبات تخزينها دون فقدان المعلومات
- تحسين سرعة النقل عبر الشبكة بسبب تقليل الحجم ونقل الملف الفردي
- تجميع عدة ملفات ذات صلة معًا في أرشيف واحد لإدارة فعالة
- تجميع الكود الخاص بك في أرشيف واحد لأغراض التوزيع
- تأمين بياناتك باستخدام التشفير، وهو مطلب شائع في الوقت الحاضر
- ضمان سلامة معلوماتك لتجنب التغييرات العرضية والضارة في بياناتك
تجعل هذه الميزات ملفات ZIP إضافة مفيدة لمجموعة أدوات Python الخاصة بك إذا كنت تبحث عن طريقة مرنة وقابلة للحمل وموثوقة لأرشفة ملفاتك الرقمية.
هل يمكن لـ Python التعامل مع ملفات ZIP؟
نعم! تحتوي بايثون على العديد من الأدوات التي تتيح لك التعامل مع ملفات ZIP. بعض هذه الأدوات متوفر في مكتبة بايثون القياسية. وتشمل هذه الأدوات مكتبات منخفضة المستوى لضغط البيانات وفك ضغطها باستخدام خوارزميات ضغط محددة، مثل zlib وbz2 وlzma وغيرها.
يوفر بايثون أيضًا وحدةً متقدمةً تُسمى zipfile، مُصممةً خصيصًا لإنشاء ملفات ZIP وقراءتها وكتابتها واستخراجها وسرد محتوياتها. في هذا البرنامج التعليمي، ستتعلم عن zipfile في بايثون وكيفية استخدامه بفعالية.
التعامل مع ملفات ZIP الموجودة باستخدام zipfile
يوفر ملف zipfile في بايثون فئات ودوال سهلة الاستخدام تُمكّنك من إنشاء ملفات ZIP وقراءتها وكتابتها واستخراجها وسرد محتوياتها. إليك بعض الميزات الإضافية التي يدعمها ملف zipfile:
- ملفات ZIP أكبر من 4 جيجابايت (ملفات ZIP64)
- فك تشفير البيانات
- عدة خوارزميات ضغط، مثل Deflate وBzip2 وLZMA
- التحقق من سلامة المعلومات باستخدام CRC32
انتبه إلى أن zipfile يعاني من بعض القيود. على سبيل المثال، قد تكون ميزة فك تشفير البيانات الحالية بطيئة جدًا لأنها تستخدم شفرة بايثون فقط. لا تستطيع الوحدة التعامل مع إنشاء ملفات ZIP مشفرة. وأخيرًا، لا تدعم أيضًا استخدام ملفات ZIP متعددة الأقراص. على الرغم من هذه القيود، لا يزال zipfile أداة رائعة ومفيدة. تابع القراءة لاستكشاف إمكانياته.
فتح ملفات ZIP للقراءة والكتابة
في وحدة zipfile، ستجد فئة ZipFile. تعمل هذه الفئة بشكل مشابه لدالة ()open المدمجة في بايثون، مما يسمح لك بفتح ملفات ZIP باستخدام أوضاع مختلفة. وضع القراءة (“r”) هو الوضع الافتراضي. يمكنك أيضًا استخدام أوضاع الكتابة (“w”)، والإضافة (“a”)، والحصرية (“x”). ستتعرف على كل منها لاحقًا.
يُطبّق ZipFile بروتوكول إدارة السياق، ما يُتيح لك استخدام الفئة في عبارة with. تتيح لك هذه الميزة فتح ملف ZIP والعمل عليه بسرعة دون القلق بشأن إغلاقه بعد الانتهاء من العمل.
لتجهيز بيئة العمل، ضع الموارد في مجلد يُسمى /python-zipfile في مجلدك الرئيسي. بعد وضع الملفات في مكانها الصحيح، انتقل إلى المجلد الذي أنشأته حديثًا وابدأ جلسة تفاعلية مع بايثون هناك.
للتحضير، ستبدأ بقراءة ملف ZIP المسمى sample.zip. للقيام بذلك، يمكنك استخدام ZipFile في وضع القراءة:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... archive.printdir()
...
File Name Modified Size
hello.txt 2021-09-07 19:50:10 83
lorem.md 2021-09-07 19:50:10 2609
pyarabic.md 2021-09-07 19:50:10 428
يمكن أن تكون الوسيطة الأولى لمُهيئ ملف ZipFile سلسلة نصية تُمثل مسار ملف ZIP الذي تريد فتحه. يمكن لهذه الوسيطة أيضًا قبول كائنات شبيهة بالملفات والمسارات. في هذا المثال، ستستخدم مسارًا نصيًا.
الوسيطة الثانية لـ ZipFile هي سلسلة نصية من حرف واحد تُمثل الوضع الذي ستستخدمه لفتح الملف. كما تعلمت في بداية هذا القسم، يُمكن لـ ZipFile قبول أربعة أوضاع مُحتملة، حسب احتياجاتك. الوسيطة الافتراضية الوضع هي “r”، لذا يُمكنك حذفها إذا كنت ترغب في فتح الأرشيف للقراءة فقط.
داخل عبارة with، يمكنك استدعاء دالة .printdir() على ملف archive. يحمل متغير archive الآن نسخة ملف ZipFile نفسه. توفر هذه الدالة طريقة سريعة لعرض محتوى ملف ZIP الأساسي على شاشتك. مخرجات الدالة بتنسيق جدولي سهل الاستخدام بثلاثة أعمدة مفيدة:
File NameModifiedSize
إذا كنت تريد التأكد من استهداف ملف ZIP صالح قبل محاولة فتحه، فيمكنك تغليف ZipFile في عبارة try … except والتقاط أي استثناء BadZipFile:
>>> import zipfile
>>> try:
... with zipfile.ZipFile("sample.zip") as archive:
... archive.printdir()
... except zipfile.BadZipFile as error:
... print(error)
...
File Name Modified Size
hello.txt 2021-09-07 19:50:10 83
lorem.md 2021-09-07 19:50:10 2609
pyarabic.md 2021-09-07 19:50:10 428
>>> try:
... with zipfile.ZipFile("bad_sample.zip") as archive:
... archive.printdir()
... except zipfile.BadZipFile as error:
... print(error)
...
File is not a zip file
نجح المثال الأول في فتح ملف sample.zip دون إثارة استثناء BadZipFile. وذلك لأن ملف sample.zip يحتوي على صيغة ZIP صالحة. أما المثال الثاني، فلم ينجح في فتح ملف bad_sample.zip، لأن الملف ليس ملف ZIP صالحًا.
للتحقق من صحة ملف ZIP، يمكنك أيضًا استخدام الدالة is_zipfile():
>>> import zipfile
>>> if zipfile.is_zipfile("sample.zip"):
... with zipfile.ZipFile("sample.zip", "r") as archive:
... archive.printdir()
... else:
... print("File is not a zip file")
...
File Name Modified Size
hello.txt 2021-09-07 19:50:10 83
lorem.md 2021-09-07 19:50:10 2609
pyarabic.md 2021-09-07 19:50:10 428
>>> if zipfile.is_zipfile("bad_sample.zip"):
... with zipfile.ZipFile("bad_sample.zip", "r") as archive:
... archive.printdir()
... else:
... print("File is not a zip file")
...
File is not a zip file
في هذه الأمثلة، ستستخدم جملة شرطية مع ()is_zipfile كشرط. تأخذ هذه الدالة وسيطة filename التي تحتوي على مسار ملف ZIP في نظام الملفات لديك. يمكن لهذه الوسيطة قبول كائنات نصية، أو شبيهة بالملف، أو شبيهة بالمسار. تُرجع الدالة القيمة True إذا كان filename ملف ZIP صالحًا. وإلا، تُرجع القيمة False.
لنفترض الآن أنك تريد إضافة ملف hello.txt إلى أرشيف hello.zip باستخدام ZipFile. للقيام بذلك، يمكنك استخدام وضع الكتابة (“w”). يفتح هذا الوضع ملف ZIP للكتابة. إذا كان ملف ZIP المستهدف موجودًا، فسيقوم وضع “w” بحذفه وكتابة أي محتوى جديد تُمرر إليه.
ملاحظة: إذا كنت تستخدم ZipFile مع ملفات موجودة، فعليك توخي الحذر عند استخدام وضع “w”. قد يؤدي ذلك إلى حذف ملف ZIP وفقدان جميع محتوياته الأصلية.
إذا لم يكن ملف ZIP المستهدف موجودًا، فسيقوم ZipFile بإنشائه لك عند إغلاق الأرشيف:
>>> import zipfile
>>> with zipfile.ZipFile("hello.zip", mode="w") as archive:
... archive.write("hello.txt")
...
بعد تشغيل هذا الكود، سيكون لديك ملف hello.zip في مجلد python-zipfile/. إذا أدرجتَ محتوى الملف باستخدام .printdir()، فستلاحظ وجود ملف hello.txt هناك. في هذا المثال، ستستدعي .write() على كائن ZipFile. تتيح لك هذه الطريقة كتابة ملفات الأعضاء في أرشيفات ZIP. يُرجى ملاحظة أن الوسيطة .write() يجب أن تكون ملفًا موجودًا.
يتيح لك وضع الإضافة (“a”) إضافة ملفات أعضاء جديدة إلى ملف ZIP موجود. لا يقتطع هذا الوضع الأرشيف، لذا يبقى محتواه الأصلي آمنًا. إذا لم يكن ملف ZIP المستهدف موجودًا، فسيُنشئ وضع “a” ملفًا جديدًا لك، ثم يُضيف أي ملفات إدخال تُمررها كمعامل إلى دالة .write().
لتجربة الوضع “a”، قم بإضافة ملف new_hello.txt إلى أرشيف hello.zip الذي قمت بإنشائه حديثًا:
>>> import zipfile
>>> with zipfile.ZipFile("hello.zip", mode="a") as archive:
... archive.write("new_hello.txt")
...
>>> with zipfile.ZipFile("hello.zip") as archive:
... archive.printdir()
...
File Name Modified Size
hello.txt 2021-09-07 19:50:10 83
new_hello.txt 2021-08-31 17:13:44 13
هنا، يمكنك استخدام وضع الإضافة لإضافة new_hello.txt إلى ملف hello.zip. ثم شغّل .printdir() للتأكد من وجود الملف الجديد في ملف ZIP.
يدعم ZipFile أيضًا وضعًا حصريًا (“x”). يتيح لك هذا الوضع إنشاء ملفات ZIP جديدة حصريًا وكتابة ملفات أعضاء جديدة فيها. ستستخدم هذا الوضع الحصري عند إنشاء ملف ZIP جديد دون الكتابة فوق ملف موجود. إذا كان الملف المستهدف موجودًا بالفعل، فسيظهر الخطأ FileExistsError.
أخيرًا، إذا قمت بإنشاء ملف ZIP باستخدام الوضع “w” أو “a” أو “x” ثم قمت بإغلاق الأرشيف دون إضافة أي ملفات أعضاء، فسيقوم ZipFile بإنشاء أرشيف فارغ بتنسيق ZIP المناسب.
قراءة البيانات الوصفية من ملفات ZIP
لقد استخدمتَ بالفعل دالة .printdir(). إنها طريقة مفيدة يمكنك استخدامها لعرض محتويات ملفات ZIP بسرعة. إلى جانب دالة .printdir()، توفر فئة ZipFile عدة طرق سهلة لاستخراج البيانات الوصفية من ملفات ZIP الموجودة.
وفيما يلي ملخص لتلك التوابع:
| التابع | الوصف |
|---|---|
.getinfo(filename) | يُرجع كائن ZipInfo بمعلومات حول ملف العضو المُقدَّم بواسطة filename. يُرجى ملاحظة أن filename يجب أن يحتوي على مسار الملف الهدف داخل ملف ZIP الأساسي. |
.infolist() | يقوم بإرجاع قائمة من كائنات ZipInfo، كائن واحد لكل ملف عضو. |
.namelist() | تُرجع قائمة بأسماء جميع ملفات الأعضاء في الأرشيف الأساسي. الأسماء في هذه القائمة هي وسيطات صالحة لـ .getinfo(). |
باستخدام هذه الأدوات الثلاث، يمكنك استرجاع معلومات مفيدة كثيرة حول محتوى ملفات ZIP. على سبيل المثال، انظر المثال التالي الذي يستخدم .getinfo():
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... info = archive.getinfo("hello.txt")
...
>>> info.file_size
83
>>> info.compress_size
83
>>> info.filename
'hello.txt'
>>> info.date_time
(2021, 9, 7, 19, 50, 10)
كما تعلمت في الجدول أعلاه، يأخذ .getinfo() ملف عضو كحجة ويعيد كائن ZipInfo مع معلومات عنه.
تحتوي كائنات ZipInfo على عدة سمات تتيح لك استرجاع معلومات قيّمة حول ملف العضو المستهدف. على سبيل المثال، يُظهر .file_size و.compress_size حجم الملف الأصلي والمضغوط بالبايت على التوالي. كما تحتوي الفئة على سمات مفيدة أخرى، مثل .filename و.date_time، اللتين تُرجعان اسم الملف وتاريخ آخر تعديل.
ملاحظة: افتراضيًا، لا يضغط ZipFile ملفات الإدخال لإضافتها إلى الأرشيف النهائي. ولذلك، فإن حجم الملف وحجم الضغط متماثلان في المثال أعلاه. ستتعرف على المزيد حول هذا الموضوع في قسم ضغط الملفات والمجلدات أدناه.
باستخدام دالة .infolist()، يمكنك استخراج المعلومات من جميع الملفات في أرشيف معين. إليك مثال يستخدم هذه الطريقة لإنشاء تقرير بسيط يحتوي على معلومات حول جميع الملفات الأعضاء في أرشيف sample.zip:
>>> import datetime
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... for info in archive.infolist():
... print(f"Filename: {info.filename}")
... print(f"Modified: {datetime.datetime(*info.date_time)}")
... print(f"Normal size: {info.file_size} bytes")
... print(f"Compressed size: {info.compress_size} bytes")
... print("-" * 20)
...
Filename: hello.txt
Modified: 2021-09-07 19:50:10
Normal size: 83 bytes
Compressed size: 83 bytes
--------------------
Filename: lorem.md
Modified: 2021-09-07 19:50:10
Normal size: 2609 bytes
Compressed size: 2609 bytes
--------------------
Filename: pyarabic.md
Modified: 2021-09-07 19:50:10
Normal size: 428 bytes
Compressed size: 428 bytes
--------------------
تتكرر حلقة for عبر كائنات ZipInfo من .infolist()، مسترجعةً اسم الملف، وتاريخ آخر تعديل، والحجم الطبيعي، والحجم المضغوط لكل ملف عضو. في هذا المثال، استخدمتَ datetime لتنسيق التاريخ بطريقة سهلة القراءة.
إذا كنت تحتاج فقط إلى إجراء فحص سريع على ملف ZIP وإدراج أسماء ملفات أعضائه، فيمكنك استخدام .namelist():
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... for filename in archive.namelist():
... print(filename)
...
hello.txt
lorem.md
pyarabic.md
نظرًا لأن أسماء الملفات في هذا الإخراج عبارة عن وسيطات صالحة لـ .getinfo()، فيمكنك الجمع بين هاتين الطريقتين لاسترداد المعلومات حول ملفات الأعضاء المحددة فقط.
على سبيل المثال، قد يكون لديك ملف ZIP يحتوي على أنواع مختلفة من الملفات (.docx، .xlsx، .txt، وهكذا). بدلاً من الحصول على المعلومات الكاملة باستخدام .infolist()، ما عليك سوى الحصول على معلومات ملفات .docx. بعد ذلك، يمكنك تصفية الملفات حسب امتدادها واستدعاء .getinfo() لملفات .docx فقط. جرّبها!
القراءة من ملفات الأعضاء والكتابة إليها
أحيانًا يكون لديك ملف ZIP وتحتاج إلى قراءة محتوى ملف عضو مُحدد دون استخراجه. للقيام بذلك، يمكنك استخدام .read(). تأخذ هذه الطريقة اسم ملف العضو وتُرجع محتواه كبايتات:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... for line in archive.read("hello.txt").split(b"\n"):
... print(line)
...
b'Hello, Pythonista!'
b''
b'Welcome to pyarabic!'
b''
b"Ready to try Python's zipfile module?"
b''
لاستخدام .read()، عليك فتح ملف ZIP للقراءة أو الإضافة. لاحظ أن .read() تُرجع محتوى الملف الهدف كتدفق بايتات. في هذا المثال، ستستخدم .split() لتقسيم التدفق إلى أسطر، باستخدام حرف تغذية السطر “\n” كفاصل. ولأن .split() يعمل على كائن بايتات، ستحتاج إلى إضافة حرف b في بداية السلسلة المستخدمة كمعامل.
يقبل ()ZipFile.read أيضًا وسيطة موضعية ثانية تُسمى pwd. تتيح لك هذه الوسيطة توفير كلمة مرور لقراءة الملفات المشفرة.
>>> import zipfile
>>> with zipfile.ZipFile("sample_pwd.zip", mode="r") as archive:
... for line in archive.read("hello.txt", pwd=b"secret").split(b"\n"):
... print(line)
...
b'Hello, Pythonista!'
b''
b'Welcome to pyarabic!'
b''
b"Ready to try Python's zipfile module?"
b''
>>> with zipfile.ZipFile("sample_pwd.zip", mode="r") as archive:
... for line in archive.read("hello.txt").split(b"\n"):
... print(line)
...
Traceback (most recent call last):
...
RuntimeError: File 'hello.txt' is encrypted, password required for extraction
في المثال الأول، تُدخل كلمة المرور secret لقراءة ملفك المشفر. تقبل وسيطة pwd قيمًا من نوع البايتات. إذا استخدمت .read() على ملف مشفر دون إدخال كلمة المرور المطلوبة، فسيحدث خطأ وقت التشغيل (RuntimeError)، كما هو موضح في المثال الثاني.
ملاحظة: يدعم ملف zip الخاص بلغة بايثون فك التشفير. ولكنه لا يدعم إنشاء ملفات ZIP مشفرة. لذلك، ستحتاج إلى استخدام مُؤرشف ملفات خارجي لتشفير ملفاتك.
تتضمن بعض برامج أرشيف الملفات الشائعة 7z وWinRAR لنظام Windows، وArk وGNOME Archive Manager لنظام Linux، وArchiver لنظام macOS.
بالنسبة لملفات ZIP الكبيرة والمشفرة، تذكّر أن عملية فك التشفير قد تكون بطيئة للغاية لأنها مُنفَّذة بلغة بايثون خالصة. في هذه الحالات، فكّر في استخدام برنامج متخصص لإدارة أرشيفاتك بدلاً من استخدام zipfile.
إذا كنت تعمل بانتظام مع ملفات مشفرة، فقد ترغب في تجنب إدخال كلمة مرور فك التشفير في كل مرة تستدعي فيها دالة .read() أو أي دالة أخرى تقبل وسيطة كلمة مرور. في هذه الحالة، يمكنك استخدام ()ZipFile.setpassword لتعيين كلمة مرور عامة:
>>> import zipfile
>>> with zipfile.ZipFile("sample_pwd.zip", mode="r") as archive:
... archive.setpassword(b"secret")
... for file in archive.namelist():
... print(file)
... print("-" * 20)
... for line in archive.read(file).split(b"\n"):
... print(line)
...
hello.txt
--------------------
b'Hello, Pythonista!'
b''
b'Welcome to pyarabic!'
b''
b"Ready to try Python's zipfile module?"
b''
lorem.md
--------------------
b'# Lorem Ipsum'
b''
b'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
...
مع .setpassword()، ما عليك سوى إدخال كلمة مرورك مرة واحدة. يستخدم ZipFile هذه الكلمة الفريدة لفك تشفير جميع ملفات الأعضاء.
على النقيض من ذلك، إذا كان لديك ملفات ZIP بكلمات مرور مختلفة لملفات الأعضاء الفردية، فأنت بحاجة إلى توفير كلمة المرور المحددة لكل ملف باستخدام وسيطة pwd في .read():
>>> import zipfile
>>> with zipfile.ZipFile("sample_file_pwd.zip", mode="r") as archive:
... for line in archive.read("hello.txt", pwd=b"secret1").split(b"\n"):
... print(line)
...
b'Hello, Pythonista!'
b''
b'Welcome to pyarabic!'
b''
b"Ready to try Python's zipfile module?"
b''
>>> with zipfile.ZipFile("sample_file_pwd.zip", mode="r") as archive:
... for line in archive.read("lorem.md", pwd=b"secret2").split(b"\n"):
... print(line)
...
b'# Lorem Ipsum'
b''
b'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
...
في هذا المثال، تستخدم secret1 ككلمة مرور لقراءة hello.txt وsecret2 لقراءة lorem.md. ملاحظة أخيرة: عند استخدام وسيطة pwd، فإنك تُلغي أي كلمة مرور على مستوى الأرشيف قد تكون قد عيّنتها باستخدام .setpassword().
ملاحظة: يؤدي استدعاء
.read()على ملف ZIP يستخدم طريقة ضغط غير مدعومة إلى ظهور خطأ NotImplementedError. كما يظهر خطأ إذا لم تكن وحدة الضغط المطلوبة متوفرة في تثبيت بايثون.
إذا كنت تبحث عن طريقة أكثر مرونة للقراءة من ملفات الأعضاء وإنشاء ملفات أعضاء جديدة وإضافتها إلى الأرشيف، فإن ()ZipFile.open هي الأنسب لك. وكما هو الحال مع دالة ()open المدمجة، تُطبّق هذه الطريقة بروتوكول إدارة السياق، وبالتالي فهي تدعم عبارة with:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... with archive.open("hello.txt", mode="r") as hello:
... for line in hello:
... print(line)
...
b'Hello, Pythonista!\n'
b'\n'
b'Welcome to pyarabic!\n'
b'\n'
b"Ready to try Python's zipfile module?\n"
في هذا المثال، تفتح ملف hello.txt للقراءة. الوسيطة الأولى لـ .open() هي الاسم، الذي يشير إلى ملف العضو الذي تريد فتحه. الوسيطة الثانية هي الوضع، والذي يكون افتراضيًا “r” كالمعتاد. تقبل ()ZipFile.open أيضًا وسيطة كلمة مرور لفتح الملفات المشفرة. تعمل هذه الوسيطة بنفس طريقة وسيطة كلمة المرور المكافئة في .read().
يمكنك أيضًا استخدام .open() مع وضع “w”. يتيح لك هذا الوضع إنشاء ملف عضو جديد، وكتابة محتوى فيه، ثم إضافته إلى الأرشيف الأساسي، والذي يجب فتحه في وضع الإضافة:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="a") as archive:
... with archive.open("new_hello.txt", "w") as new_hello:
... new_hello.write(b"Hello, World!")
...
13
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... archive.printdir()
... print("------")
... archive.read("new_hello.txt")
...
File Name Modified Size
hello.txt 2021-09-07 19:50:10 83
lorem.md 2021-09-07 19:50:10 2609
pyarabic.md 2021-09-07 19:50:10 428
new_hello.txt 1980-01-01 00:00:00 13
------
b'Hello, World!'
في مقتطف الكود الأول، افتح ملف sample.zip في وضع الإضافة (“a”). ثم أنشئ ملف new_hello.txt باستدعاء دالة .open() في وضع “w”. تُرجع هذه الدالة كائنًا شبيهًا بالملف يدعم دالة .write()، مما يسمح لك بكتابة بايتات في الملف المُنشأ حديثًا.
ملاحظة: يجب عليك إدخال اسم ملف غير موجود لـ
.open(). إذا استخدمت اسم ملف موجود مسبقًا في الأرشيف الأساسي، فسيؤدي ذلك إلى ملف مكرر واستثناء UserWarning.
في هذا المثال، تكتب b’Hello, World!’ في ملف new_hello.txt. عند انتهاء عملية التنفيذ من جملة with الداخلية، يكتب بايثون بايتات الإدخال إلى ملف العضو. عند انتهاء جملة with الخارجية، يكتب بايثون ملف new_hello.txt في ملف ZIP الأساسي، sample.zip.
يؤكد مقطع الكود الثاني أن ملف new_hello.txt أصبح الآن ملفًا عضويًا في ملف sample.zip. من التفاصيل التي يجب ملاحظتها في مخرجات هذا المثال أن دالة .write() تُعيّن تاريخ تعديل الملف المُضاف حديثًا إلى 1980-01-01 00:00:00، وهو سلوك غريب يجب مراعاته عند استخدام هذه الطريقة.
قراءة محتوى الملفات كنص
كما تعلمت في القسم السابق، يمكنك استخدام التابعين .read() و.write() لقراءة الملفات والكتابة إليها دون الحاجة لاستخراجها من أرشيف ZIP. يعمل كل من التابعين حصريًا مع البايتات.
مع ذلك، عند وجود أرشيف ZIP يحتوي على ملفات نصية، قد ترغب في قراءة محتواها كنص بدلًا من بايتات. هناك طريقتان على الأقل للقيام بذلك. يمكنك استخدام:
لأن دالة ()ZipFile.read تُرجع محتوى ملف العضو المستهدف على هيئة بايتات، يمكن لدالة .decode() العمل على هذه البايتات مباشرةً. تُفكك دالة .decode() كائن البايتات إلى سلسلة نصية باستخدام تنسيق ترميز أحرف مُحدد.
إليك كيفية استخدام .decode() لقراءة النص من ملف hello.txt في أرشيف sample.zip:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... text = archive.read("hello.txt").decode(encoding="utf-8")
...
>>> print(text)
Hello, Pythonista!
Welcome to pyarabic!
Ready to try Python's zipfile module?
في هذا المثال، تقرأ محتوى ملف hello.txt كبايتات. ثم تستدعي دالة .decode() لفك تشفير البايتات وتحويلها إلى سلسلة نصية باستخدام ترميز UTF-8. لتعيين قيمة الترميز، استخدم السلسلة النصية “utf-8”. مع ذلك، يمكنك استخدام أي ترميز صالح آخر، مثل UTF-16 أو cp1252، والذي يمكن تمثيله كسلاسل نصية غير حساسة لحالة الأحرف. تجدر الإشارة إلى أن “utf-8” هي القيمة الافتراضية لقيمة الترميز في دالة .decode().
من المهم أن تتذكر ضرورة معرفة تنسيق ترميز الأحرف لأي ملف عضو ترغب في معالجته باستخدام .decode() مسبقًا. إذا استخدمت ترميزًا خاطئًا للأحرف، فلن يتمكن الكود الخاص بك من فك تشفير البايتات الأساسية وتحويلها إلى نص بشكل صحيح، وقد ينتهي بك الأمر بكمية هائلة من الأحرف غير القابلة للفك.
الخيار الثاني لقراءة النص من ملف عضو هو استخدام كائن io.TextIOWrapper، الذي يوفر تدفقًا نصيًا مؤقتًا. هذه المرة، ستحتاج إلى استخدام .open() بدلاً من .read(). إليك مثال على استخدام io.TextIOWrapper لقراءة محتوى ملف العضو hello.txt كتدفق نصي:
>>> import io
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... with archive.open("hello.txt", mode="r") as hello:
... for line in io.TextIOWrapper(hello, encoding="utf-8"):
... print(line.strip())
...
Hello, Pythonista!
Welcome to pyarabic!
Ready to try Python's zipfile module?
في جملة with الداخلية في هذا المثال، تفتح ملف العضو hello.txt من ملف sample.zip. ثم تُمرر الكائن الثنائي الناتج، hello، كمعامل إلى io.TextIOWrapper. يُنشئ هذا تدفقًا نصيًا مؤقتًا عن طريق فك تشفير محتوى hello باستخدام ترميز UTF-8. ونتيجةً لذلك، تحصل على تدفق نصي مباشر من ملف العضو المستهدف.
كما هو الحال مع .encode()، تأخذ فئة io.TextIOWrapper وسيطة ترميز. يجب عليك دائمًا تحديد قيمة لهذه الوسيطة، لأن ترميز النص الافتراضي يعتمد على النظام الذي يُشغّل الشيفرة، وقد لا تكون القيمة الصحيحة للملف الذي تحاول فك ترميزه.
استخراج الملفات من أرشيفات ZIP
يُعد استخراج محتوى أرشيف معين من أكثر العمليات شيوعًا على ملفات ZIP. بناءً على احتياجاتك، قد ترغب في استخراج ملف واحد في كل مرة أو جميع الملفات دفعةً واحدة.
تتيح لك دالة ()ZipFile.extract إنجاز المهمة الأولى. تأخذ هذه الطريقة اسم ملف عضو وتستخرجه إلى دليل مُحدد يُشير إليه المسار. مسار الوجهة افتراضيًا هو الدليل الحالي:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... archive.extract("new_hello.txt", path="output_dir/")
...
'output_dir/new_hello.txt'
الآن، سيكون ملف new_hello.txt في مجلد output_dir/. إذا كان اسم الملف المستهدف موجودًا بالفعل في مجلد الإخراج، فستقوم دالة .extract() باستبداله دون طلب تأكيد. إذا لم يكن مجلد الإخراج موجودًا، فستقوم دالة .extract() بإنشائه. لاحظ أن دالة .extract() تُرجع مسار الملف المستخرج.
يجب أن يكون اسم ملف العضو هو الاسم الكامل للملف كما ترجعه دالة .namelist(). ويمكن أيضًا أن يكون كائن ZipInfo يحتوي على معلومات الملف.
يمكنك أيضًا استخدام دالة .extract() مع الملفات المشفرة. في هذه الحالة، ستحتاج إلى توفير وسيطة كلمة المرور المطلوبة أو تعيين كلمة مرور مستوى الأرشيف باستخدام دالة .setpassword().
لاستخراج جميع ملفات الأعضاء من أرشيف، يمكنك استخدام دالة .extractall(). وكما يوحي اسمها، تستخرج هذه الطريقة جميع ملفات الأعضاء إلى مسار الوجهة، وهو المجلد الحالي افتراضيًا:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... archive.extractall("output_dir/")
...
بعد تشغيل هذا الكود، سيُحفظ جميع محتويات ملف sample.zip الحالي في مجلد output_dir/. إذا مررتَ مجلدًا غير موجود إلى دالة .extractall()، فستُنشئ هذه الدالة المجلد تلقائيًا. وأخيرًا، إذا كان أيٌّ من ملفات الأعضاء موجودًا بالفعل في مجلد الوجهة، فستُستبدله دالة .extractall() دون طلب تأكيدك، لذا توخَّ الحذر.
إذا كنت تحتاج فقط إلى استخراج بعض ملفات الأعضاء من أرشيف معين، فيمكنك استخدام وسيطة الأعضاء. تقبل هذه الوسيطة قائمةً من ملفات الأعضاء، والتي يجب أن تكون جزءًا من قائمة الملفات الكاملة في الأرشيف المطلوب. وأخيرًا، وكما هو الحال مع دالة .extract()، تقبل دالة .extractall() أيضًا وسيطة كلمة مرور لاستخراج الملفات المشفرة.
إغلاق ملفات ZIP بعد الاستخدام
أحيانًا يكون من الملائم فتح ملف ZIP مُحدد دون استخدام جملة with. في هذه الحالات، ستحتاج إلى إغلاق الأرشيف يدويًا بعد الاستخدام لإكمال أي عمليات كتابة وتحرير الموارد المُستخدَمة.
للقيام بذلك، يمكنك استدعاء .close() على كائن ZipFile:
>>> import zipfile
>>> archive = zipfile.ZipFile("sample.zip", mode="r")
>>> # Use archive in different parts of your code
>>> archive.printdir()
File Name Modified Size
hello.txt 2021-09-07 19:50:10 83
lorem.md 2021-09-07 19:50:10 2609
pyarabic.md 2021-09-07 19:50:10 428
new_hello.txt 1980-01-01 00:00:00 13
>>> # Close the archive when you're done
>>> archive.close()
>>> archive
<zipfile.ZipFile [closed]>
يؤدي استدعاء دالة .close() إلى إغلاق الأرشيف نيابةً عنك. يجب عليك استدعاء دالة .close() قبل الخروج من البرنامج. وإلا، فقد لا تُنفَّذ بعض عمليات الكتابة. على سبيل المثال، إذا فتحت ملف ZIP لإضافة ملفات أعضاء جديدة (“a”)، فعليك إغلاق الأرشيف لكتابة الملفات.
إنشاء ملفات ZIP الخاصة بك وتعبئتها واستخراجها
حتى الآن، تعلمتَ كيفية التعامل مع ملفات ZIP الحالية. تعلمتَ قراءة وكتابة وإضافة ملفات الأعضاء إليها باستخدام أوضاع ZipFile المختلفة. تعلمتَ أيضًا كيفية قراءة البيانات الوصفية ذات الصلة وكيفية استخراج محتوى ملف ZIP معين.
في هذا القسم، ستُبرمج بعض الأمثلة العملية التي ستساعدك على تعلم كيفية إنشاء ملفات ZIP من عدة ملفات إدخال ومن مجلد كامل باستخدام zipfile وأدوات بايثون الأخرى. ستتعلم أيضًا كيفية استخدام zipfile لضغط الملفات والمزيد.
إنشاء ملف ZIP من ملفات عادية متعددة
أحيانًا تحتاج إلى إنشاء أرشيف ZIP من عدة ملفات مترابطة. بهذه الطريقة، يمكنك جمع جميع الملفات في حاوية واحدة لتوزيعها عبر شبكة حاسوبية أو مشاركتها مع الأصدقاء أو الزملاء. لتحقيق ذلك، يمكنك إنشاء قائمة بالملفات المستهدفة وكتابتها في أرشيف باستخدام ZipFile وتكرار حلقي:
>>> import zipfile
>>> filenames = ["hello.txt", "lorem.md", "pyarabic.md"]
>>> with zipfile.ZipFile("multiple_files.zip", mode="w") as archive:
... for filename in filenames:
... archive.write(filename)
...
هنا، أنشئ كائن ZipFile باسم الأرشيف المطلوب كمعامل أول. يتيح لك وضع “w” كتابة ملفات الأعضاء في ملف ZIP النهائي.
تتكرر حلقة for عبر قائمة ملفات الإدخال وتكتبها في ملف ZIP الأساسي باستخدام دالة .write(). بمجرد انتهاء عملية التنفيذ من جملة with، يُغلق ZipFile الأرشيف تلقائيًا، ويحفظ التغييرات نيابةً عنك. الآن، لديك أرشيف multiple_files.zip يحتوي على جميع الملفات من قائمة الملفات الأصلية.
إنشاء ملف ZIP من دليل
يُعد تجميع محتوى مجلد في أرشيف واحد استخدامًا شائعًا آخر لملفات ZIP. توفر بايثون العديد من الأدوات التي يمكنك استخدامها مع zipfile لإنجاز هذه المهمة. على سبيل المثال، يمكنك استخدام pathlib لقراءة محتوى مجلد معين. باستخدام هذه المعلومات، يمكنك إنشاء أرشيف حاوية باستخدام ZipFile.
في الدليل python-zipfile/، لديك دليل فرعي يسمى source_dir/، مع المحتوى التالي:
source_dir/
│
├── hello.txt
├── lorem.md
└── pyarabic.md
في source_dir/، لديك ثلاثة ملفات عادية فقط. ولأن المجلد لا يحتوي على مجلدات فرعية، يمكنك استخدام ()pathlib.Path.iterdir لتكرار محتواه مباشرةً. مع وضع هذه الفكرة في الاعتبار، إليك كيفية إنشاء ملف ZIP من محتوى source_dir/:
>>> import pathlib
>>> import zipfile
>>> directory = pathlib.Path("source_dir/")
>>> with zipfile.ZipFile("directory.zip", mode="w") as archive:
... for file_path in directory.iterdir():
... archive.write(file_path, arcname=file_path.name)
...
>>> with zipfile.ZipFile("directory.zip", mode="r") as archive:
... archive.printdir()
...
File Name Modified Size
pyarabic.md 2021-09-07 19:50:10 428
hello.txt 2021-09-07 19:50:10 83
lorem.md 2021-09-07 19:50:10 2609
في هذا المثال، تُنشئ كائن pathlib.Path من دليل المصدر. تُنشئ عبارة with الأولى كائن ZipFile جاهزًا للكتابة. ثم يُرجع استدعاء ()iterdir مُكررًا على مُدخلات الدليل الأساسي.
نظرًا لعدم وجود أي مجلدات فرعية في source_dir/، فإن دالة .iterdir() تُنتج ملفات فقط. تُكرر حلقة for الملفات وتكتبها في الأرشيف.
في هذه الحالة، تُمرر file_path.name إلى الوسيطة الثانية لـ .write(). تُسمى هذه الوسيطة arcname، وتحتوي على اسم ملف العضو داخل الأرشيف الناتج. جميع الأمثلة التي شاهدتها حتى الآن تعتمد على القيمة الافتراضية لـ arcname، وهو نفس اسم الملف الذي تُمرر كمُعامل أول لـ .write().
إذا لم تقم بتمرير file_path.name إلى arcname، فسيكون دليل المصدر الخاص بك في جذر ملف ZIP الخاص بك، والذي يمكن أن يكون أيضًا نتيجة صالحة اعتمادًا على احتياجاتك.
ضغط الملفات والدلائل
إذا كانت ملفاتك تشغل مساحة كبيرة على القرص، فننصحك بضغطها. يدعم ملف zipfile في بايثون بعض طرق الضغط الشائعة. مع ذلك، لا تقوم الوحدة بضغط ملفاتك افتراضيًا. لتصغير حجم ملفاتك، ستحتاج إلى توفير طريقة ضغط صريحة لملف ZipFile.
عادةً، يُستخدم مصطلح “مخزّن” للإشارة إلى ملفات الأعضاء المكتوبة في ملف ZIP دون ضغط. ولذلك، تُسمى طريقة الضغط الافتراضية في ZipFile بـ ZIP_STORED، والتي تشير في الواقع إلى ملفات الأعضاء غير المضغوطة المُخزّنة ببساطة في الأرشيف المُحتوي.
طريقة هي الوسيطة الثالثة لمُهيئ ملف ZipFile. إذا كنت ترغب في ضغط ملفاتك أثناء كتابتها في أرشيف ZIP، فيمكنك تعيين هذه الوسيطة إلى أحد الثوابت التالية:compression
| الثابت | طريقة الضغط | الوحدة المطلوبة |
|---|---|---|
zipfile.ZIP_DEFLATED | Deflate | zlib |
zipfile.ZIP_BZIP2 | Bzip2 | bz2 |
zipfile.ZIP_LZMA | LZMA | lzma |
هذه هي طرق الضغط المتاحة حاليًا مع ZipFile. سيؤدي استخدام طريقة أخرى إلى ظهور خطأ NotImplementedError. لا تتوفر طرق ضغط إضافية لملفات zip اعتبارًا من إصدار Python 3.13.
كشرط إضافي، إذا اخترت إحدى هذه الطرق، يجب أن تكون وحدة الضغط التي تدعمها متوفرة في تثبيت بايثون. وإلا، فستواجه استثناء RuntimeError، وسيتعطل الكود.
من الحجج المهمة الأخرى في ZipFile عند ضغط ملفاتك مستوى الضغط. يتحكم هذا المستوى في مستوى الضغط المستخدم.
باستخدام طريقة Deflate، يمكن لـ compresslevel أخذ أعداد صحيحة من 0 إلى 9. باستخدام طريقة Bzip2، يمكنك تمرير أعداد صحيحة من 1 إلى 9. في كلتا الحالتين، عندما يزداد مستوى الضغط، تحصل على ضغط أعلى وسرعة ضغط أقل.
ملاحظة: الملفات الثنائية، مثل PNG وJPG وMP3 وما شابهها، تستخدم نوعًا من الضغط. لذلك، قد لا يؤدي إضافتها إلى ملف ZIP إلى تقليل حجم البيانات، لأنها مضغوطة بالفعل إلى حد ما.
لنفترض الآن أنك تريد أرشفة وضغط محتوى مجلد معين باستخدام طريقة Deflate، وهي الطريقة الأكثر استخدامًا في ملفات ZIP. للقيام بذلك، يمكنك تشغيل الكود التالي:
>>> import pathlib
>>> from zipfile import ZipFile, ZIP_DEFLATED
>>> directory = pathlib.Path("source_dir/")
>>> with ZipFile("comp_dir.zip", "w", ZIP_DEFLATED, compresslevel=9) as archive:
... for file_path in directory.rglob("*"):
... archive.write(file_path, arcname=file_path.relative_to(directory))
...
في هذا المثال، مرر القيمة 9 إلى compresslevel للحصول على أقصى ضغط. لتوفير هذه الوسيطة، استخدم كلمة مفتاحية. يجب عليك القيام بذلك لأن compresslevel ليس الوسيطة الموضعية الرابعة لمُهيئ ملف ZipFile.
بعد تشغيل هذا الكود، سيكون لديك ملف comp_dir.zip في مجلدك الحالي. بمقارنة حجم هذا الملف بحجم ملف sample.zip الأصلي، ستلاحظ انخفاضًا ملحوظًا في الحجم.
استخراج الملفات والدلائل
من أكثر العمليات شيوعًا التي ستُجريها على ملفات ZIP استخراج محتواها إلى مجلد مُحدد في نظام الملفات لديك. لقد تعلّمت بالفعل أساسيات استخدام .extract() و.extractall() لاستخراج ملف واحد أو جميع الملفات من الأرشيف.
كمثال إضافي، ارجع إلى ملف sample.zip. في هذه المرحلة، يحتوي الأرشيف على أربعة ملفات من أنواع مختلفة. لديك ملفان بصيغة .txt وملفان بصيغة .md. لنفترض الآن أنك تريد استخراج ملفات .md فقط. للقيام بذلك، يمكنك تشغيل الكود التالي:
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
... for file in archive.namelist():
... if file.endswith(".md"):
... archive.extract(file, "output_dir/")
...
'output_dir/lorem.md'
'output_dir/pyarabic.md'
تفتح عبارة with ملف sample.zip للقراءة. تتكرر الحلقة على كل ملف في الأرشيف باستخدام namelist()، بينما تتحقق عبارة الشرط مما إذا كان اسم الملف ينتهي بالامتداد .md. إذا كان كذلك، فاستخرج الملف المطلوب إلى مجلد الهدف، output_dir/، باستخدام .extract().
يُعدّ ملف zipfile في بايثون أداةً مفيدةً لقراءة الملفات وكتابتها وضغطها وفك ضغطها واستخراجها من أرشيفات ZIP. وقد أصبح تنسيق ملفات ZIP معيارًا في هذا المجال، مما يسمح لك بتجميع بياناتك الرقمية وضغطها اختياريًا.
تتضمن فوائد استخدام ملفات ZIP أرشفة الملفات ذات الصلة معًا، وتوفير مساحة القرص، وتسهيل نقل البيانات عبر شبكات الكمبيوتر، وتجميع كود Python لأغراض التوزيع، والمزيد.
لقد تعلمتَ أيضًا كيفية استخدام zipfile من سطر الأوامر لسرد ملفات ZIP وإنشائها واستخراجها. بفضل هذه المعرفة، أنت جاهز لأرشفة بياناتك الرقمية وضغطها ومعالجتها بكفاءة باستخدام تنسيق ملفات ZIP.
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.