سلاسل F أو كيفية جعل الكود أسرع وأكثر قابلية للقراءة



لدى Python 3 طرق لتنسيق السلاسل ، واحدة منها أفضل من غيرها. لكن دعونا لا نتقدم على أنفسنا - ما نوع التنسيق الذي نتحدث عنه؟ في كل مرة نريد فيها تحية مستخدم بالاسم ، نحتاج إلى إدراج سلسلة باسم في سلسلة القالب. تحتوي معظم إدخالات السجل المفيدة أيضًا على قيم متغيرة. وهنا مثال على ذلك:

integer = 42 string = 'FORTY_TWO' print('string number %s, or simply %d' % (string, integer)) print('string number {}, or simply {}'.format(string, integer)) print(f'string number {string}, or simply {integer}') 

الطريقة الأولى ، التنسيق مع عامل التشغيل٪ ، جاءت في Python من C - وهي تقلد وظيفة printf. كانت هذه الطريقة الأولى في بيثون ، وتظل الطريقة الوحيدة (التي تمت مناقشتها في المقال) في بيثون الإصدار 2.5 وما دونه.

الطريقة الثانية هي طريقة str.format التي تنتمي إلى فئة السلسلة المضمنة. لقد جاء مع Python 3.0 ، وتم نقله إلى الإصدار 2.6. لقد تم التوصية بهذه الطريقة كجمل غني.

الطريقة الثالثة ، سلسلة f ، ظهرت في بيثون الإصدار 3.6. كما هو موضح في PEP-0498 ، كان الدافع وراء إنشاء طريقة جديدة لتنسيق السلاسل هو أوجه القصور في الطرق الحالية ، والتي وصفها المؤلفون بأنها عرضة للخطأ ، وليست مرنة بما فيه الكفاية وليست أنيقة:
الدافع وراء هذا PEP هو الرغبة في الحصول على طريقة أكثر بساطة لتنسيق السلاسل في Python. الطرق الحالية للتنسيق إما أن تكون عرضة للخطأ أو غير مرنة أو مرهقة.
لذلك ، لدينا ثلاث طرق لحل مشكلة واحدة. ولكن ربما هذه مسألة ذوق وتفضيل شخصي؟ ربما ، لكن أسلوب الكود الخاص بك (وخاصة الكود في مشروع مع عدد كبير من المشاركين) سيستفيد بالتأكيد من التوحيد. في أفضل الأحوال ، يجب عليك استخدام طريقة واحدة لتنسيق السلاسل ، عندها ستصبح قراءة الكود أسهل. لكن أي طريقة تختار؟ وهل هناك فرق في أداء الكود؟

دعنا نحاول الإجابة على سؤال حول الأداء بشكل تجريبي:

 import timeit setup = """ integer = 42 string = 'FORTY_TWO' """.strip() percent_stmt ="'Number %s or simply %d' % (string, integer)" call_stmt = "'Number {} or simply {}'.format(string, integer)" fstr_stmt = """f'Number {string} or simply {integer}'""" def time(stmt): return f"{timeit.timeit(stmt, setup, number=int(1e7)):.3f}" print(f"Timing percent formating: | {time(percent_stmt)}") print(f"Timing call formating: | {time(call_stmt)}") print(f"Timing f-string formating: | {time(fstr_stmt)}") 

النتائج على MacBook مع Python 3.7:

 Timing percent formating: | 2.025 Timing call formating: | 2.943 Timing f-string formating: | 1.348 

الفرق كبير. حتى الآن ، قم بتشغيل بحث regex على ".format" وأعد كتابة مئات التعبيرات؟ من حيث المبدأ ، المهمة بسيطة ولكنها تستغرق وقتًا طويلاً. بالإضافة إلى فرصة ارتكاب خطأ ووضع خطأ في رمز العمل السابق! يبدو أن هناك مجالا للأتمتة. في الواقع ، هناك مكتبات يمكنها تحويل معظم التعبيرات إلى سلاسل f: flynt ، pyupgrade .

فلينت سهل الاستخدام. على سبيل المثال ، قم بتشغيل التحويل على الكود المصدري للقارورة:

 38f9d3a65222:~ ikkamens$ git clone https://github.com/pallets/flask.git Cloning into 'flask'... ... Resolving deltas: 100% (12203/12203), done. 38f9d3a65222:~ ikkamens$ flynt flask Flynt run has finished. Stats: Execution time: 0.623s Files modified: 18 Expressions transformed: 43 Character count reduction: 241 (0.04%) _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. Please run your tests before commiting. Report bugs as github issues at: https://github.com/ikamensh/flynt Thank you for using flynt! Fstringify more projects and recommend it to your colleagues! _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. 38f9d3a65222:~ ikkamens$ 

تجدر الإشارة أيضًا إلى إمكانية تحويل التعبيرات التي تشغل عدة أسطر ، وجمع إحصائيات حول التغييرات التي تم إجراؤها. تحدد العلامة - line_length XX حد طول السطر بعد التحويل. يسمح لك Flynt بالاتصال بـ pyupgrade باستخدام علامة --upgrade.

يتضمن Pyupgrade المزيد من الوظائف ، ويمكنه تنظيف الكود الخاص بك من العديد من القطع الأثرية لـ Python 2 - مثل الوراثة من الكائن ، وتحديد أسماء الفئات بشكل فائق ، وغير ذلك الكثير . تم تصميم Pyupgrade للاستخدام مع الالتزام المسبق ، أداة مساعدة لتعديل التعليمات البرمجية تلقائيًا قبل الالتزام.

من الأفضل تحويل المصدر في gita أو عنصر تحكم إصدار آخر. إنه أمر يستحق إجراء الاختبارات والنظر في التغييرات بنفسك (باستخدام بيئات git diff أو PyCharm). طالما أننا نعيش بين من يهتمون ، أن الشفرة أصبحت أقصر من الأحرف ، فإن التحويل الاستباقي سيوفر أيضًا وقتهم. بعد كل شيء ، سوف يبدأ شخص ما عاجلاً أم آجلاً في القيام بأيديهم ما يمكن جعله أداة مساعدة. تعمل F-strings على Python 3.6+ فقط ، ولكن لن تكون هذه مشكلة قريبًا لأن الإصدارات الأخرى ستصبح قديمة .

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

الاستنتاجات:

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

Source: https://habr.com/ru/post/ar462179/


All Articles