اذهب إلى المحتوى

منسق شيفرات بايثون الصارم Black


محمد الخضور

تعرفنا في المقال السابق قواعد تنسيق الشيفرات ودور المنسق Black في بايثون من هذه السلسلة على مفهوم تنسيق الشيفرة مبينين مجموعة من القواعد الواجب تطبيقها على الشيفرة المصدرية لمنحها مظهرًا معينًا. كما تعرفنا على منسِّق Black وهو أداة لتنسيق الشيفرات، إذ تنسق الشيفرة المصدرية تلقائيًا إلى شكلٍ مقروء ومتناغم، دون التأثير على سلوك البرنامج وأداءه؛ وسنتعرف في هذا المقال على آلية تثبيت واستخدام وتخصيص هذه الأداة.

ينسّق Black الشيفرات تلقائيًا في ملفات بايثون ذات اللاحقة ‎.py، ورغم ضرورة فهمك لقواعد التنسيق الواردة في المقال السابق، إلا أن Black وحده قادر على إجراء كافة عمليات التنسيق الفعلية، ففي حال كنت تعمل على مشروعٍ برمجي ضمن فريق، فسيوفّر عليكم استخدام Black الكثير من الجدالات حول كيفية تنسيق الشيفرات.

وفي الواقع من غير الممكن تغيير أغلبية التنسيقات التي يجريها Black، ومن هنا جاءت تسميته بالصارم. أما عن اسمه (Black الأسود)، فهو مستوحى من اقتباس مالك مصنع السيارات هينري فورد حول خيارات ألوان السيارات التي يقدمها لعملائه، إذ يقول "يمكنك اختيار أي لون تريده، طالما أنك اخترت اللون الأسود".

تثبيت الأداة Black

نثبّت Black باستخدام أداة تثبيت الحزم pip الافتراضية في بايثون. ولإجراء ذلك، في حال استخدامك لنظام التشغيل ويندوز، افتح نافذة سطر أوامر، واكتب ضمنها ما يلي:

C:\Users\Al\>python -m pip install --user black

أما إذا كنت تستخدم أحد نظاميّ ماك أو لينكس، فافتح نافذة موجه الأوامر مُستخدمًا الأمر python3 بدلًا من python كما هو الحال في ويندوز (الأمر الواجب مراعاته في كافّة تعليمات بايثون الواردة في هذا المقال):

$ python3 -m pip install --user black

ويعد الخيار m- مسؤولًا عن إعلام بايثون لتشغيل الوحدة pip كتطبيق، مع ملاحظة أن بعض الوحدات في بايثون مضبوطة لتعمل كتطبيق افتراضيًا.

ثمّ نتحقق من كون التثبيت قد تم بنجاح عبر تشغيل الأمر python -m black، وعندها يجب أن تظهر رسالة مفادها عدم وجود مسارات معطاة No paths given أو ما من شيء لفعله Nothing to do، بدلًا من ظهور رسالة تفيد بعدم وجود وحدة باسم black أو No module named black.

تشغيل Black من سطر الأوامر

من الممكن تشغيل المنسّق Black لأي ملف بايثون باستخدام سطر الأوامر، كما أنّ محررات النصوص وبيئات التطوير المتكاملة قادرة على تشغيل Black في الخلفية أثناء عملك ضمنها. وللحصول على التعليمات المتعلقة بكيفية تشغيل Black مع محررات نصوص مثل Jupyter و Visual Studio Code و PyCharm وغيرها، من خلال زيارة الصفحة الرئيسية للمنسّق Black على psf/black.

فعلى سبيل المثال، لنفرض أننا نريد تنسيق ملف باسم yourScript.py تلقائيًا، لذا نفتح نافذة سطر الأوامر ونكتب فيها الأمر التالي ونشغله (مع مراعاة تبديل الأمر python إلى python3 في حال استخدام أحد نظامي ماك أو لينكس):

C:\Users\Al>python -m black yourScript.py

وبمجرد تشغيل الأمر السابق، سينُسَق محتوى الملف yourScript.py وفقًا لقواعد تنسيق Black.

وفي حال كون متغير البيئة PATH مضبوطًا ليشغّل Black مباشرةً، عندها يكفي كتابة الشيفرة التالية لتنسيق الملف yourScript.py تلقائيًا:

C:\Users\Al>black yourScript.py

كما من الممكن جعل Black يعمل على كل الملفات ذات اللاحقة py. ضمن مجلد معين، وذلك بتحديد هذا المجلد ضمن الأمر بدلًا من تحديد اسم ملف معيّن، فمثلًا الأمر التالي في ويندوز سينسّق كافة الملفات ذات اللاحقة py. الموجودة ضمن المجلد C:\yourPythonFiles بما يتضمّن الملفات الموجودة في المجلدات الفرعية منه:

C:\Users\Al>python -m black C:\yourPythonFiles

فتحديد مجلد كامل لتنسيق ملفاته يعد خيارًا مفيدًا جدًا في حال كون مشروعك يتضمّن عدة ملفات بايثون، كبديل عن كتابة أمر خاص لتنسيق كل ملف وحده.

ورغم كون Black صارمًا في طريقة تنسيقه للشيفرات، إلا أن الفقرات الثلاث التالية تتضمّن بعض الخيارات الممكن تغيرها فيه، وللاطلاع على كامل الخيارات التي يوفرها Black، شغّل الأمر python -m black --help في نافذة سطر الأوامر.

تعديل إعدادات طول السطر في Black

إن الطول المعياري للسطر الواحد في بايثون هو 80 محرفًا، ويعود تاريخ الأسطر ذات الثمانين محرفًا إلى حقبة الحوسبة باستخدام البطاقات المُثقبّة punch cards في عشرينيات القرن الماضي، حين طرحت شركة IBM بطاقات مثقبة ذات 80 عمود و 12 سطر، ليستمر استخدام معيار الثمانين محرفًا في الطابعات والشاشات ونوافذ سطر الأوامر لعدّة عقود لاحقة.

ولكن مع ظهور الشاشات عالية الدقة في القرن الواحد والعشرين، غدت هذه الشاشات قادرة على عرض نصوص يزيد عرضها عن ثمانين محرف. ففي حين أن الأسطر الأطول قد تقلل من عبء التمرير الرأسي لاستعراض الملف، وبالمقابل فالأسطر الأقصر تقلل من اكتظاظ الشيفرات في السطر الواحد، ما قد يسهل من عملية مقارنة شيفرتين جنبًا إلى جنب (بتقسيم الشاشة رأسيًا) دون الحاجة إلى التمرير أفقيًا أثناء المقارنة.

يستخدم Black افتراضيًا أسطرًا ذات 88 محرفًا، مضيفًا 10% زيادة عن القيمة المعيارية (80 محرف)، أما عن تفضيلي الشخصي فهو 120 محرف للسطر، ولجعل Black ينسق الشيفرة جاعلًا الحد الأعظمي لطول السطر 120 محرفًا على سبيل المثال، نستخدم خيار سطر الأوامر l 120-، إذ يبدو الأمر في نظام ويندوز كما يلي:

C:\Users\Al>python -m black -l 120 yourScript.py

وبغض النظر عما تختاره بخصوص الحد الأقصى لعدد المحارف بالسطر، الأهم أن يكون هذا الخيار موحدًا لكافّة ملفات بايثون في المشروع الواحد.

تعطيل إعداد حصر السلاسل النصية بعلامات اقتباس مزدوجة

يغير Black صياغة أي سلسلة نصية في الشيفرة تلقائيًا لتصبح محصورة بين علامتي اقتباس مزدوجتين، وذلك في حال استخدام علامتي اقتباس مفردتين لحصرها، إلا في حال كون السلسلة النصية تتضمّن أصلًا علامات اقتباس مزدوجة، فعندها يستخدم علامات مفردة، لنأخذ مثلًا ملفًا باسم yourScript.py يتضمن الشيفرات التالية:

a = 'Hello'
b = "Hello"
c = 'Al\'s cat, Zophie.'
d = 'Zophie said, "Meow"'
e = "Zophie said, \"Meow\""
f = '''Hello'''

وبتشغيل Black على الملف السابق، سينسقه ليصبح بالشكل:

1 a = "Hello"
b = "Hello"
c = "Al's cat, Zophie."
2 d = 'Zophie said, "Meow"'
e = 'Zophie said, "Meow"'
3 f = """Hello"""

إن تفضيل Black لاستخدام علامات الاقتباس المزدوجة لإحاطة السلاسل النصية يجعل من الشيفرة المكتوبة بلغة بايثون شبيهة بتلك المكتوبة بلغات برمجة أخرى، إذ تستخدم معظم اللغات الأخرى علامات الاقتباس المزدوجة لصياغة السلاسل النصية.

ومن الجدير بالملاحظة أنه وباستخدام Black على الشيفرة السابقة فأن السلاسل النصية في المتغيرات a و b و c قد حُصرت ضمن علامات اقتباس مزدوجة، في حين بقيت علامة الاقتباس المفردة للسلسلة في المتغير d لتجنب الخلط مع العلامة المزدوجة الموجودة أصلًا ضمن السلسلة في السطر 2، كما نلاحظ أن Black قد استبدل علامات الاقتباس المفردة الثلاثية في السطر 3 الدالة على كون هذه السلسة متعددة الأسطر multiline، بعلامة اقتباس مزدوجة ثلاثية.

وفي حال رغبتك بترك علامات الاقتباس على حالها دون تغييرها من قبل Black، فاستخدم ضمن استدعاءه الخيار S- في نافذة سطر الأوامر (مع ملاحظة أنّ حرف S كبير هنا)، فعلى سبيل المثال، في حال تشغيل Black على الملف yourScript.py الأصلي في نظام ويندوز، سيظهر الخرج التالي:

C:\Users\Al>python –m black -S yourScript.py
All done!
1 file left unchanged.

كما من الممكن استخدام كلا خياري الحد الأقصى لمحارف السطر l- وخيار عدم تغيير علامات الاقتباس S- في سطرٍ واحد، بالشكل:

C:\Users\Al>python –m black –l 120 -S yourScript.py

استعراض التغييرات التي أجراها Black

رغم كون تعديلات Black تنسيقية بحتة لا تشتمل مثلًا على تغيير أسماء المتغيرات أو أي تغيير في سلوك الشيفرة البرمجي، إلا أنك قد لا تفضل التغييرات التنسيقية التي أجراها، وفي حال رغبتك بالرجوع إلى تنسيقات شيفرتك الأصلية، فبإمكانك إما استخدام نظام إدارة الإصدارات أو الرجوع إلى نسخك الاحتياطية الخاصة.

ولعل الخيار البديل الأفضل هو معاينة التغييرات التي سيجريها Black قبل تطبيقها الفعلي من خلال تشغيل Black مع استخدام خيار سطر الأوامر diff--، والذي يبدو في نظام ويندوز بالشكل:

C:\Users\Al>python -m black --diff yourScript.py

سيعطي هذا الأمر خرجًا يمثّل التغييرات التي سيجريها Black في صياغة لبيان الاختلافات شبيهة بتلك شائعة الاستخدام في برمجيات إدارة الشيفرات، إلا أنها مقروءة وواضحة للبشر. فمثلًا لو تضمّن الملف yourScript.py السطر البرمجي[weights=[42.0,3.1415,2.718، وبتشغيل الخيار diff-- مع Black، سيكون الخرج بالشكل:

C:\Users\Al\>python -m black --diff yourScript.py
--- yourScript.py       2020-12-07 02:04:23.141417 +0000
+++ yourScript.py       2020-12-07 02:08:13.893578 +0000
@@ -1 +1,2 @@
-weights=[42.0,3.1415,2.718]
+weights = [42.0, 3.1415, 2.718]

تشير علامة الناقص إلى أن Black سيحذف السطر التالي:

weights=[42.0,3.1415,2.718]

ليستبدله إلى لسطر المشار إليه بعلامة الزائد، أي:

weights = [42.0, 3.1415, 2.718]

وتذكّر دائمًا أنه ما من طريقة للرجوع عن التغييرات التي يجريها Black بعد تنفيذها، وما من سبيل سوى أن تنشئ نسخًا احتياطية من شيفرتك أو أن تستخدم إحدى برمجيات إدارة الشيفرات مثل Git وذلك قبل تطبيق تغييرات Black عليها.

تعطيل عمل Black على أجزاء محددة من الشيفرة

مع كامل روعة عمل Black، إلا أنك قد لا ترغب بإجرائه لتغييرات على أجزاء معينة من شيفرتك، فمثلًا أنا شخصيًا أفضّل اتباع طريقتي الخاصة لإنشاء التباعد في تعليمات الإسناد المتعددة المتعلقة ببعضها بغية ترتيبها، كما في المثال التالي:

# Set up constants for different time amounts:
SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR   = 60 * SECONDS_PER_MINUTE
SECONDS_PER_DAY    = 24 * SECONDS_PER_HOUR
SECONDS_PER_WEEK   = 7  * SECONDS_PER_DAY

ومع استخدام Black على هذا الجزء، فإنه سيحذف الفراغات الإضافية قبل معامل الإسناد =، جاعلًا مقروئية التعليمات أقل من وجهة نظري، بالشكل:

# Set up constants for different time amounts:
SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE
SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR
SECONDS_PER_WEEK = 7 * SECONDS_PER_DAY

ولإعلام Black برغبتنا بعدم إجراء أي تغييرات على مقطع برمجي معيّن، يكفي حصره ما بين التعليقين fmt: off # و fmt: on #، ليتابع بعده إجراء التنسيقات بشكل طبيعي:

# Set up constants for different time amounts:
# fmt: off
SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR   = 60 * SECONDS_PER_MINUTE
SECONDS_PER_DAY    = 24 * SECONDS_PER_HOUR
SECONDS_PER_WEEK   = 7  * SECONDS_PER_DAY
# fmt: on

وبذلك وبتشغيل Black على هذا الملف، فإنه لن يغير من التباعدات الخاصة أو أي تنسيقات أخرى في الجزء من الشيفرة المحصور بين التعليقين.

الخاتمة

مما لا خلاف فيه بأن نمط تنسيق الشيفرات إجمالًا هو تفضيل شخصي، الأمر الذي لا يتنافى مع أصول مجال تطوير البرمجيات، مع وجود خطوط عريضة متفق عليها تحدد التنسيق الجيد من السيء، تاركةً فيما بينها هامشًا من الحرية للتفضيلات الشخصية.

وبما أن معظم أعمال التطوير البرمجية جماعية وليست فردية، فسواءً كنت تعمل مع مبرمجين آخرين على مشروعٍ ما، أو كنت ببساطة ستطرح سؤالًا متعلقًا بشيفرتك على أحد المبرمجين الخبراء طالبًا مساعدته، في كلتا الحالتين يعد تنسيق الشيفرة وفق النمط المقبول المعتمد أمرًا بالغ الأهمية، وهنا يبرز دور الأداة Black، ففي حين أن تنسيق الشيفرات يدويًا ضمن المحررات قد تكون مهمَّة مملة، فمن الممكن أتمتتها باستخدام أداة مثل Black، إذ استعرضنا في هذا المقال كيفية تثبيت الأداة Black وضبطها.

مما لا شك فيه أن تنسيق الشيفرات لا يقتصر على التباعد أو استخدام علامات الاقتباس المفردة أو المزدوجة، فمثلًا اختيار أسماء للمتغيرات تصف وظيفتها هو أمر مهم للمقروئية، فمع كون المنسقات الآلية قادرة على اتخاذ القرارات حيال التنسيقات النحوية الشكلية، إلا أنها غير قادرة على اتخاذ تلك المتعلقة بالدلالات اللفظية من قبيل اختيار أسماء مناسبة للمتغيرات، إذ تقع هذه المسؤوليات على عاتقك كمبرمج، الأمر الذي سنناقشه تفصيليًا في المقال القادم.

ترجمة -وبتصرف- للجزء الثاني من الفصل الثالث Code Formatting With Black من كتاب Beyond the Basic Stuff with Python لصاحبه Al Sweigarti.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...