از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
مدیران زمینه پایتون
سرفصلهای مطلب
معرفی
یکی از مبهم ترین ویژگی های پایتون که تقریباً همه برنامه نویسان پایتون، حتی مبتدیان، از آن استفاده می کنند، اما واقعا نمی دانند، این است. مدیران زمینه. شما احتمالا آنها را در قالب دیده اید with
عباراتی که معمولاً برای اولین بار در هنگام یادگیری باز کردن فایل ها در پایتون با آنها مواجه می شوند. اگرچه مدیران زمینه در ابتدا کمی عجیب به نظر می رسند، اما وقتی واقعاً در آنها غوطه ور می شویم، انگیزه و تکنیک های پشت آن را درک می کنیم، به یک سلاح جدید در زرادخانه برنامه نویسی خود دسترسی پیدا می کنیم. بنابراین بدون هیچ مقدمه ای، بیایید به آن شیرجه بزنیم!
انگیزه: مدیریت منابع
“نیاز مادر اختراع است”
برای اینکه واقعاً بفهمیم مدیر زمینه چیست و چگونه میتوانیم از آن استفاده کنیم، ابتدا باید انگیزههای پشت آن را بررسی کنیم – ضرورتهایی که باعث ایجاد این “اختراع” شد.
انگیزه اصلی مدیران زمینه مدیریت منابع است. وقتی برنامه ای می خواهد به یک منبع دسترسی پیدا کند روی کامپیوتر، آن را از سیستم عامل درخواست می کند، و سیستم عامل نیز به نوبه خود، دسته ای برای آن منبع در اختیار آن قرار می دهد. برخی از نمونه های رایج این گونه منابع فایل ها و پورت های شبکه هستند. آنچه مهم است درک این است که این منابع در دسترس محدود هستند، به عنوان مثال، یک پورت شبکه می تواند توسط یک واحد استفاده شود. process در یک زمان، و تعداد محدودی پورت در دسترس است. بنابراین هر زمان که ما باز کن یک منبع، ما باید به یاد داشته باشیم بستن آن را، به طوری که منبع آزاد شود. اما متأسفانه گفتن آن آسان تر از انجام آن است.
ساده ترین راه برای انجام مدیریت منابع مناسب فراخوانی است close
عملکرد پس از اتمام کار با منبع:
opened_file = open('readme.txt')
text = opened_file.read()
...
opened_file.close()
در اینجا ما در حال باز کردن فایلی به نام هستیم readme.txt
، خواندن فایل و ذخیره محتوای آن در یک رشته text
و پس از اتمام کار، فایل را با فراخوانی ببندید close()
روش از opened_file
هدف – شی. اکنون در نگاه اول ممکن است به نظر خوب برسد، اما در واقع، اصلا قوی نیست. اگر هر چیزی بین باز کردن فایل و بستن فایل اتفاقی غیرمنتظره رخ میدهد که باعث میشود برنامه در اجرای خط حاوی close
بیانیه، نشت منبع وجود خواهد داشت. اینها حوادث غیر منتظره چیزی هستند که ما به آن می گوییم exceptions
یک مورد معمول زمانی است که شخصی برنامه را در حین اجرا به زور می بندد.
در حال حاضر، راه مناسب برای رسیدگی به این خواهد بود استفاده از رسیدگی به استثنا، استفاده کردن try...else
بلوک ها:
try:
opened_file = open('readme.txt')
text = opened_file.read()
else:
opened_file.close()
پایتون همیشه از کد موجود در else
بلوک بدون توجه به هر اتفاقی که ممکن است رخ دهد اجرا می شود. این روشی است که برنامه نویسان زبان های دیگر مدیریت منابع را مدیریت می کنند، اما برنامه نویسان پایتون مکانیسم خاصی را دریافت می کنند که به آنها امکان می دهد همان عملکرد را بدون نیاز به تمام دیگ بخار اجرا کنند. اینجاست که مدیران زمینه وارد بازی می شوند!
پیاده سازی مدیران زمینه
اکنون که ما با مهمترین بخش در مورد درک مدیران زمینه تمام شده ایم، می توانیم به اجرای آنها بپریم. برای این آموزش یک سفارشی پیاده سازی می کنیم File
کلاس این کاملاً زائد است زیرا پایتون قبلاً این را ارائه کرده است، اما با این وجود، تمرین یادگیری خوبی خواهد بود زیرا ما همیشه میتوانیم با آن ارتباط برقرار کنیم. File
کلاسی که قبلاً در کتابخانه استاندارد وجود دارد.
روش استاندارد و «سطح پایین» برای پیادهسازی مدیر زمینه، تعریف دو روش «جادویی» در کلاسی است که میخواهید مدیریت منابع را برای آن پیادهسازی کنید. __enter__
و __exit__
. اگر در حال گمراه شدن هستید، “این روش جادویی چیست؟ من قبلاً چنین چیزی نشنیده ام” – خوب، اگر برنامه نویسی شی گرا را در پایتون شروع کرده اید، مطمئناً قبلاً با یک روش جادویی روبرو شده اید. روش __init__
.
به دلیل نبود کلمات بهتر، آنها روش های خاصی هستند که می توانید برای هوشمندتر کردن کلاس های خود تعریف کنید یا “جادو” را به آنها اضافه کنید. شما می توانید یک لیست مرجع خوب از تمام روش های جادویی موجود در پایتون پیدا کنید اینجا.
به هر حال، برای بازگشت به موضوع، قبل از شروع اجرای این دو روش جادویی، باید هدف آنها را درک کنیم. __enter__
روشی است که هنگام باز کردن منبع، یا به بیان کمی فنی تر، فراخوانی می شود – زمانی که ما “ورود” می کنیم زمینه زمان اجرا. این with
عبارت مقدار برگشتی این روش را به هدف مشخص شده در as
بند بیانیه:
class FileManager:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.opened_file = open(self.filename)
return self.opened_file
همانطور که می بینید، __enter__
روش باز کردن منبع – فایل و برگرداندن آن است. وقتی از این استفاده می کنیم FileManager
در یک with
عبارت، این متد فراخوانی می شود و مقدار بازگشتی آن به متغیر هدفی که در آن ذکر کردید متصل می شود as
عبارت:
with FileManager('readme.txt') as file:
text = file.read()
بیایید قسمت به قسمت آن را تجزیه کنیم. اولا، یک نمونه از FileManager
کلاس زمانی ایجاد می شود که ما آن را نمونه سازی می کنیم و نام فایل را ارسال می کنیم "readme.txt"
به سازنده سپس with
بیانیه شروع به کار می کند روی آن را صدا می کند __enter__
روش آن FileManager
شی و مقدار برگشتی را به file
متغیر ذکر شده در as
عبارت. سپس، در داخل with
بلاک، ما می توانیم هر کاری که می خواهیم با منبع باز شده انجام دهیم.
بخش مهم دیگر پازل این است __exit__
روش. این __exit__
متد حاوی کد پاکسازی است که باید پس از اتمام کار با منبع اجرا شود. دستورالعمل های این روش مشابه دستورالعمل های موجود در این روش خواهد بود else
بلوکی که قبلاً در مورد رسیدگی به استثناء بحث کردیم. برای تکرار، __exit__
روش شامل دستورالعمل هایی برای بستن صحیح کنترل کننده منبع است، به طوری که منبع برای استفاده بیشتر توسط برنامه های دیگر در سیستم عامل آزاد می شود.
حالا بیایید نگاهی به روش نوشتن این روش بیندازیم:
class FileManager:
def __exit__(self. *exc):
self.opened_file.close()
هر زمان که از نمونه های این کلاس در a استفاده شود with
بیانیه، این __exit__
قبل از خروج برنامه از متد فراخوانی می شود with
مسدود کردن، یا قبل از توقف برنامه به دلیل برخی استثناها. حالا بیایید به کل نگاه کنیم FileManager
کلاس تا ما یک ایده کامل داشته باشیم:
class FileManager:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.opened_file = open(self.filename)
return self.opened_file
def __exit__(self, *exc):
self.opened_file.close()
به اندازه کافی ساده، درست است؟ ما فقط عملیات باز کردن و پاکسازی را در متدهای جادویی مربوطه تعریف کردیم، و پایتون مدیریت منابع را در هر کجا که ممکن است از این کلاس استفاده شود، انجام خواهد داد. این ما را به موضوع بعدی میرساند، روشهای مختلفی که میتوانیم از کلاسهای مدیریت متن استفاده کنیم، مانند این FileManager
کلاس
استفاده از Context Managers
در اینجا چیز زیادی برای توضیح وجود ندارد، بنابراین به جای نوشتن پاراگراف های طولانی، اجازه دهید نگاهی به چند قطعه کد در این بخش بیندازیم:
file = FileManager('readme.txt')
with file as managed_file:
text = managed_file.read()
print(text)
with FileManager('readme.txt') as managed_file:
text = managed_file.read()
print(text)
def open_file(filename):
file = FileManager(filename)
return file
with open_file('readme.txt') as managed_file:
text = managed_file.read()
print(text)
می توانید ببینید که نکته کلیدی که باید به خاطر بسپارید این است که
- شیء به
with
بیانیه باید داشته باشد__enter__
و__exit__
مواد و روش ها. - این
__enter__
متد باید منبعی را که قرار است در آن استفاده شود برگرداندwith
مسدود کردن.
مهم: نکات ظریفی وجود دارد که من از آن صرف نظر کردم تا بحث را به نقطه اصلی تبدیل کنم. برای مشخصات دقیق این روش های جادویی، به مستندات پایتون مراجعه کنید اینجا.
استفاده کردن _contextlib_
این ذن پایتون – اصل راهنمای پایتون به عنوان فهرستی از کلمات قصار – بیان می کند:
“ساده بهتر از پیچیده است”
برای اینکه واقعاً این نقطه را به خانه هدایت کند، توسعه دهندگان پایتون کتابخانه ای به نام ایجاد کرده اند contextlib حاوی ابزارهای مفید در مورد مدیران زمینه، گویی که مشکل مدیریت منابع را به اندازه کافی ساده نکرده اند. ما در اینجا تنها یکی از آنها را به طور خلاصه نشان می دهیم، اما توصیه می کنیم برای اطلاعات بیشتر، اسناد رسمی پایتون را بررسی کنید.
from contextlib import contextmanager
@contextmanager
def open_file(filename):
opened_file = open(filename)
try:
yield opened_file
finally:
opened_file.close()
مانند کد بالا، ما به سادگی می توانیم تابعی را تعریف کنیم که yield
منبع حفاظت شده در a try
بیانیه، بسته شدن آن در بعد finally
بیانیه. راه دیگری برای درک آن:
- تمام مطالبی که در غیر این صورت در آن قرار می دادید
__enter__
روش، به جزreturn
بیانیه، قبل ازtry
اینجا را مسدود کنید – اساساً دستورالعمل باز کردن منبع. - به جای برگرداندن منبع، شما
yield
آن، داخل atry
مسدود کردن. - محتویات
__exit__
روش به داخل مربوطه می رودfinally
مسدود کردن.
وقتی چنین عملکردی داشتیم، می توانیم با استفاده از آن آن را تزئین کنیم contextlib.contextmanager
دکوراتور و ما خوب هستیم:
with open_file('readme.txt') as managed_file:
text = managed_file.read()
print(text)
همانطور که می بینید، تزئین شده است open_file
تابع یک مدیر زمینه را برمی گرداند و ما می توانیم مستقیماً از آن استفاده کنیم. این به ما امکان میدهد به همان اثری که ایجاد میکنیم دست پیدا کنیم FileManager
کلاس، بدون هیچ زحمتی.
نتیجه
اگر مشتاق هستید و می خواهید درباره مدیران زمینه بیشتر بخوانید، توصیه می کنم پیوندهای زیر را بررسی کنید:
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-25 09:38:06