نصائح وحيل من my Telegram-channelpythonetc ، أكتوبر 2019


إنها مجموعة جديدة من النصائح والحيل حول Python والبرمجة من قناة Telegram-channelpythonetc.

المنشورات السابقة


إذا كنت ترغب في تكرارها عبر العديد من المواد القابلة للتكرار مرة واحدة ، فيمكنك استخدام الدالة zip (لا علاقة لها بتنسيق ملف ZIP):

 from datetime import timedelta names = [ 'Eleven. Return and Revert', 'Wilderness', 'The Menagerie Inside', 'Evaporate', ] years = [ 2010, 2013, 2015, 2018, ] durations = [ timedelta(minutes=57, seconds=38), timedelta(minutes=48, seconds=5), timedelta(minutes=46, seconds=34), timedelta(minutes=43, seconds=25), ] print('Midas Fall LPs:') for name, year, duration in zip( names, years, durations ): print(f' * {name} ({year}) — {duration}') 

الإخراج:

 Midas Fall LPs: * Eleven. Return and Revert (2010) — 0:57:38 * Wilderness (2013) — 0:48:05 * The Menagerie Inside (2015) — 0:46:34 * Evaporate (2018) — 0:43:25 


مولد يمكن وقفها. يمكنك استدعاء g.close() بشكل صريح ولكن عادةً ما يقوم جامع البيانات المهملة بذلك. بمجرد استدعاء close ، يتم رفع GeneratorExit في النقطة التي توقفت فيها وظيفة المولد مؤقتًا:

 def gen(): try: yield 1 yield 2 finally: print('END') g = gen() print(next(g)) # prints '1' g.close() # prints 'END' 

مانع ثلاثة أشياء. أولاً ، لا يمكنك تحقيق قيم أثناء التعامل مع GeneratorExit :

 def gen(): try: yield 1 finally: yield 3 g = gen() next(g) g.close() # RuntimeError 

ثانياً ، لا يتم رفع الاستثناء إذا لم يبدأ المولد بعد ، لكن المولد لا يزال متوقفًا:

 def gen(): try: yield 1 finally: print('END') g = gen() g.close() # nothing print(list(g)) # prints '[]' 

ثالثًا ، close لا يفعل شيئًا إذا انتهى المولد بالفعل

 def gen(): try: yield 1 yield 2 finally: print('END') g = gen() print(list(g)) print('Closing now') g.close() # END # [1, 2] # Closing now 


تتيح لك السلاسل f تحديد عرض القيمة المطبوعة وكذلك محددات التنسيق الأخرى:

 >>> x = 42 >>> f'{x:5}+{x:15f}' ' 42+ 42.000000' 

يمكن أن تحتوي أيضًا على تعبيرات مقيمة يمكن أن تكون مفيدة عندما يكون العرض غير معروف مقدمًا:

 def print_table(matrix): cols_width = [ max(len(str(row[col])) for row in matrix) for col in range(len(matrix[0])) ] for row in matrix: for i, cell in enumerate(row): print( f'{cell:{cols_width[i]}} ', end='' ) print() albums = [ ['Eleven. Return and Revert', 2010], ['Wilderness', 2013], ['The Menagerie Inside', 2015], ['Evaporate', 2018], ] print_table(albums) 

الإخراج:

 Eleven. Return and Revert 2010 Wilderness 2013 The Menagerie Inside 2015 Evaporate 2018 


إذا كان الفصل الدراسي مشتقًا من فئة أخرى ، فيجب اشتقاق الفئة التعريفية من الفصل الدراسي من الفئة الأخرى:

 from collections import UserDict from abc import ABCMeta # ABCMeta is a metaclass of UserDict class MyDictMeta(ABCMeta): def __new__(cls, name, bases, dct): return super().__new__(cls, name, bases, dct) class MyDict(UserDict, metaclass=MyDictMeta): pass 

قد تكون فكرة جيدة الحصول على الفئة التعريفية من تلك الفئة الأخرى تلقائيًا:

 def create_my_dict_class(parents): class MyDictMeta(*[type(c) for c in parents]): def __new__(cls, name, bases, dct): return super().__new__(cls, name, bases, dct) class MyDict(*parents, metaclass=MyDictMeta): pass MyDict = create_my_dict_class((UserDict,)) 


__init__ يسمح لك بتعديل كائن مباشرة بعد الإنشاء. إذا كنت تريد التحكم في ما تم إنشاؤه ، فيجب عليك استخدام __new__ بدلاً من ذلك:

 from typing import Tuple, Dict from cached_property import cached_property class Numbers: _LOADED: Dict[Tuple[int, ...], 'Numbers'] = {} def __new__(cls, ints: Tuple[int, ...]): if ints not in cls._LOADED: obj = super().__new__(cls) cls._LOADED[ints] = obj return cls._LOADED[ints] def __init__(self, ints: Tuple[int, ...]): self._ints = ints @cached_property def biggest(self): print('calculating...') return max(self._ints) print(Numbers((4, 3, 5)).biggest) print(Numbers((4, 3, 5)).biggest) print(Numbers((4, 3, 6)).biggest) 

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


All Articles