وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

روش استفاده از متغیرهای سراسری و غیر محلی در پایتون

0 71
زمان لازم برای مطالعه: 5 دقیقه


معرفی

در این مقاله نگاهی به آن خواهیم داشت جهانی و غیرLocal متغیرها در پایتون و روش استفاده از آنها برای جلوگیری از مشکلات هنگام نوشتن کد.

ما با یک پرایمر مختصر شروع می کنیم روی قبل از اینکه به چگونگی و چرایی استفاده از متغیرهای سراسری و غیر محلی در توابع خود بپردازیم.

دامنه ها در پایتون

قبل از شروع، ابتدا باید لمس کنیم روی دامنه ها برای شما که کمتر آشنا هستید، “محدوده” به زمینه ای که یک متغیر در آن تعریف می شود و روش دسترسی یا تغییر یا به طور خاص تر آن اشاره دارد – از جایی که قابل دسترسی است.

و در برنامه نویسی، مانند زندگی، زمینه مهم است.

با ارجاع پایتون در حال حاضر، شما می توانید از زمینه استنباط کنید که من به آن اشاره می کنم زبان برنامه نویسی. اما در زمینه دیگری، پایتون می تواند اشاره ای به یک مار یا یک گروه کمدی باشد.

جهانی و محلی دامنه ها روش درک برنامه شما از زمینه متغیری است که شما به آن ارجاع می دهید.

به عنوان یک قاعده، متغیرهای تعریف شده در یک تابع یا کلاس (به عنوان یک متغیر نمونه) به طور پیش فرض محلی هستند و آنهایی که خارج از توابع و کلاس ها هستند به طور پیش فرض جهانی هستند.

Local متغیرها در پایتون

با درک آن، بیایید آن را در عمل ببینیم. ما با تعریف یک تابع با متغیر محلی خود در داخل شروع می کنیم. در این تابع متغیر را داریم fruit، که به صورت لیست اولیه و print:

def shopping_list():
    fruit = ('apple', 'banana')
    print(fruit)
    
shopping_list()

و همانطور که انتظار می رود، این مانند یک جذابیت عمل می کند:

('apple', 'banana')

اما چه اتفاقی می افتد زمانی که ما حرکت می کند print بیانیه خارج از تابع؟

def shopping_list():
    fruit = ('apple', 'banana')
    
shopping_list()
print(fruit)

ما یک خطا دریافت می کنیم”

Traceback (most recent call last):
  File "<string>", line 5, in <module>
NameError: name 'fruit' is not defined

به طور مشخص الف NameError، همانطور که میوه به صورت محلی تعریف شد و بنابراین در آن زمینه محدود می ماند.
برای اینکه برنامه ما متغیر را به صورت سراسری (خارج از تابع) درک کند، باید آن را به صورت سراسری تعریف کنیم.

متغیرهای جهانی در پایتون

اگر به جای تعریف اولیه متغیر خود در تابع، آن را به خارج منتقل کنیم و در آنجا مقداردهی اولیه کنیم، چه؟

در این حالت می توانیم خارج از تابع به آن ارجاع دهیم و همه چیز کار می کند.

اما اگر سعی کنیم متغیر میوه در داخل را دوباره تعریف کنیم shopping_list، این تغییرات به متغیر جهانی اصلی به روز نمی شوند، در عوض به صورت محلی ایزوله می شوند:

fruit = ('apple', 'banana')

def shopping_list():
    fruit = ('apple', 'banana', 'grapes')

shopping_list()
print(fruit)

خروجی:

('apple', 'banana')

این به این دلیل است که fruit ما در آن اصلاح کرده ایم shopping_list() تابع یک متغیر محلی جدید است. ما آن را ایجاد کرده‌ایم، یک مقدار به آن اختصاص داده‌ایم و بعد از آن هیچ کاری انجام نداده‌ایم. این به طور موثر کد کاملاً زائد است. این print() بیانیه مقدار متغیر جهانی را که در محدوده آن قرار دارد را چاپ می کند.

پیشنهاد می‌کنیم بخوانید:  شروع به کار با PostmanTesting یک برنامه به معنای چیزی بیشتر از کلیک کردن در اطراف تا زمانی که چیزی خراب شود یا امتحان ورودی های مختلف تا زمانی که چیزی درست کار نمی کند، است. در حالی که این یک راه خوب برای پیدا کردن هر چیزی است که ممکن است خراب شود روی سمت کاربر رو به روی برنامه، به دلیل استفاده نادرست - آنچه مورد غفلت قرار می گیرد ...

این جهانی کلمه کلیدی

اگر بخواهیم آن تغییرات در متغیر سراسری ما منعکس شود، به جای ایجاد یک متغیر محلی جدید، تنها کاری که باید انجام دهیم این است که global کلمه کلیدی. این به ما این امکان را می دهد که ارتباط برقرار کنیم fruit متغیر در واقع یک متغیر جهانی است:

fruit = ('pineapple', 'grapes')

def shopping_list():
    global fruit
    fruit = ('pineapple', 'grapes', 'apple', 'banana')

shopping_list()
print(fruit)

و مطمئناً متغیر سراسری با مقادیر جدید اصلاح می‌شود، بنابراین یکی را فراخوانی می‌کنیم print(fruit)، مقادیر جدید چاپ می شوند:

('pineapple', 'grapes', 'apple', 'banana')

با تعریف زمینه متغیر میوه ای که ما از آن به عنوان متغیر جهانی یاد می کنیم، سپس می توانیم آن را دوباره تعریف کرده و به محتوای دلخواه خود تغییر دهیم و بدانیم که تغییراتی که در تابع ایجاد می کنیم انجام خواهد شد.

ما همچنین می‌توانیم یک متغیر سراسری در تابع خود تعریف کنیم و بتوانیم به آن در هر جای دیگری ارجاع داده و به آن دسترسی داشته باشیم.

def shopping_list():
    global fruit
    fruit = ('pineapple', 'grapes', 'apple', 'banana')


shopping_list()
print(fruit)

این خروجی می دهد:

('pineapple', 'grapes', 'apple', 'banana')

ما حتی می‌توانیم یک متغیر جهانی را در یک تابع اعلام کنیم و در تابع دیگری به آن دسترسی داشته باشیم، بدون اینکه در تابع دوم آن را به عنوان جهانی تعیین کنیم:

def shopping_list():
    global fruit
    fruit = ('pineapple', 'grapes', 'apple', 'banana')

def print_list():
    print(fruit)
    
shopping_list()
print(fruit)
print_list()

این منجر به:

('pineapple', 'grapes', 'apple', 'banana')
('pineapple', 'grapes', 'apple', 'banana')

هنگام استفاده از متغیرهای جهانی احتیاط کنید

در حالی که امکان تغییر یک متغیر سراسری به صورت محلی ابزار کوچکی است، اما باید با کمی احتیاط با آن رفتار کنید. بازنویسی بیش از حد و نادیده گرفتن دامنه دستوری برای فاجعه است که با اشکالات و رفتارهای غیرمنتظره پایان می یابد.

همیشه مهم است که اطمینان حاصل کنید که یک متغیر را فقط در شرایطی که به آن نیاز دارید دستکاری می کنید، و در غیر این صورت آن را به حال خود رها کنید، این محرک اصلی پشت اصل است. کپسوله سازی.

قبل از حرکت، نگاهی گذرا به یک مثال از یک مشکل احتمالی خواهیم داشت روی به برخی از روش هایی که متغیرهای سراسری می توانند در کد شما مفید باشند:

fruit = ('pineapple', 'grapes', 'apple', 'banana')

def first_item():
    global fruit
    fruit = fruit(0)
    
def iterate():
    global fruit
    for entry in fruit:
        print(entry)
    
iterate()
print(fruit)
first_item()
print(fruit)

با اجرای کد بالا، خروجی زیر را دریافت می کنیم:

pineapple
grapes
apple
banana
('pineapple', 'grapes', 'apple', 'banana')
pineapple

در این مثال ما به متغیر در هر دو تابع ارجاع می دهیم، first_item() و iterate(). همه چیز به نظر می رسد اگه زنگ بزنیم خوب کار میکنه iterate() و سپس first_item().

اگر ما معکوس پس از آن دستور یا تلاش برای تکرار، با یک مشکل بزرگ مواجه می شویم:

first_item()
print(fruit)
iterate()
print(fruit)

اکنون این خروجی می دهد:

pineapple
p
i
n
e
a
p
p
l
e
pineapple

برای مثال، fruit اکنون رشته ای است که از طریق آن تکرار می شود. بدتر این است که این اشکال تا زمانی که احتمالاً خیلی دیر نشده است، خود را نشان نمی دهد. کد اول ظاهرا خوب اجرا شد.

پیشنهاد می‌کنیم بخوانید:  روش نصب NVIDIA CUDA Toolkit روی اوبونتو

اکنون این مشکل آشکار است روی هدف ما مستقیماً یک متغیر جهانی را دستکاری کردیم – ببینید، تغییر کرده است. با این حال، در ساختارهای پیچیده تر، ممکن است به طور تصادفی اصلاح متغیر جهانی یک گام بیش از حد برداشته شود و نتایج غیرمنتظره ای به دست آید.

این غیر محلی کلمه کلیدی

فقط به این دلیل که شما باید محتاط باشید به این معنی نیست که متغیرهای سراسری نیز فوق العاده مفید نیستند. هر زمان که بخواهید متغیری را بدون ارائه آن در دستور بازگشت، مانند شمارنده، به روز کنید، متغیرهای سراسری می توانند مفید باشند. آنها همچنین با توابع تو در تو بسیار مفید هستند.

برای کسانی از شما استفاده می کنید پایتون 3+، می توانید استفاده کنید nonlocal، یک کلمه کلیدی که عملکرد بسیار مشابهی دارد global، اما در درجه اول زمانی تأثیر می گذارد که در متدها تودرتو باشد. nonlocal اساساً یک میان از جهانی و محلی محدوده.

از آنجایی که برای بیشتر نمونه‌های خود از فهرست‌های خرید و میوه‌ها استفاده کرده‌ایم، می‌توانیم به یک تابع پرداخت فکر کنیم که کل خریدها را جمع می‌کند:

def shopping_bill(promo=False):
    items_prices = (10, 5, 20, 2, 8)
    pct_off = 0

    def half_off():
        nonlocal pct_off
        pct_off = .50

    if promo:
        half_off()

    total = sum(items_prices) - (sum(items_prices) * pct_off)
    print(total)
    
shopping_bill(True)

با اجرای کد بالا، خروجی را دریافت می کنیم:

22.5

به این ترتیب متغیر شمارش سراسری همچنان محلی برای تابع بیرونی است و در سطح بالاتر مختل نمی شود (یا وجود خواهد داشت). این به شما اجازه می دهد تا اصلاح کننده ها را به توابع خود اضافه کنید.

شما همیشه می توانید این را با تلاش تأیید کنید print pct_off خارج از روش قبض خرید:

NameError: name 'pct_off' is not defined

اگر از آن استفاده کرده بودیم global کلمه کلیدی به جای nonlocal کلمه کلیدی، چاپ pct_off منجر به:

0.5

نتیجه

در پایان روز، کلمات کلیدی جهانی (و غیر محلی) یک ابزار هستند و زمانی که به درستی استفاده شوند می توانند فرصت های زیادی را برای کد شما باز کنند. من شخصاً از هر دوی این کلمات کلیدی اغلب در کد خود استفاده می کنم و با تمرین کافی خواهید دید که واقعاً چقدر قدرتمند و مفید هستند.

مثل همیشه، از شما برای خواندن و هک مبارک بسیار سپاسگزارم!

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-13 10:44:05

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید