دامنه عملکرد پایتون – انجمن DEV
هنگامی که از نامی در برنامه پایتون استفاده می کنید، مانند نام تابع نام متغیر و غیره، پایتون نام را در یک فضای نام ایجاد، تغییر می دهد یا جستجو می کند. فضای نام، فهرست کاملی از نامهایی است که در یک زمینه مشخص وجود دارد.
دو نوع فضای نام وجود دارد، فضای نام جهانی و محلی فضای نام.
محدوده یک شی مکان هایی را در برنامه تعیین می کند که در آن می توان به آن دسترسی داشت، به طور پیش فرض، اشیا فقط از داخل فضای نامی که در آن قرار دارند قابل دسترسی هستند. اشیاء در فضای نام جهانی از هر کجای برنامه قابل دسترسی هستند، این نامهایی هستند که در سطح بالای یک ماژول یا یک اسکریپت اعلان میشوند، یعنی داخل یک تابع، یک کلاس و غیره نیستند. از سوی دیگر، نامهایی که در یک بلوک هایی مانند یک تابع محلی برای آن بلوک هستند و فقط در داخل بلوک قابل دسترسی هستند.
وقتی تابعی را تعریف می کنیم، پایتون a را تنظیم می کند فضای نام محلی برای عملکرد هر شیء اعلام شده در داخل تابع فقط در داخل تابع قابل دسترسی خواهد بود، گفته می شود شیء محلی برای آن تابع است. تلاش برای دسترسی به اشیاء محلی خارج از محدوده آنها باعث ایجاد الف خواهد شد NameError
. مثلا:
def demo():
x = 100
print(x)
demo()
//100
print(x)
//NameError: name 'x' is not defined
اشیاء داخل یک تابع به گونهای محلیسازی میشوند که با اشیایی با نامهای مشابه خارج از آن تابع تصادف نمیکنند. این اجازه میدهد که یک نام برای اشیاء مختلف در حوزههای مختلف بدون ایجاد تداخل استفاده شود.
اگر تابعی نامی را اعلام کند که در فضای نام جهانی نیز وجود دارد، نام محلی بر نام جهانی اولویت دارد و آن را فقط در داخل آن تابع بازنویسی می کند. مثال:
x = 200
def demo():
x = 100
print(x)
demo()
//100
print(x)
//200
در مثال بالا، دو متغیر متمایز با یک نام وجود دارد x
، یکی در فضای نام جهانی با مقدار 200
و دیگری در فضای نام محلی تابع دمو با مقدار 100
. ارزش x
بنابراین، با مکانی که ما از آن استفاده می کنیم تعیین می شود. ایجاد هرگونه تغییر در'x'
داخل دموی تابع به هیچ وجه بر مقدار the تأثیر نمی گذارد 'x'
خارج از محدوده آن
وضوح نام، قانون LEGB
وقتی یک شی را با نام ذکر می کنیم، مفسر پایتون از یک رویکرد درون به بیرون پیروی می کند تا شی مورد نظر ما را شناسایی کند. این رویکرد اغلب به عنوان قانون LEGB شناخته می شود که مخفف Local, Enclosing, Global, Built-in است. این قانون را می توان به صورت زیر خلاصه کرد:
- محلی، اول : ابتدا این نام را در فضای نام محلی جستجو کنید و در صورت موجود بودن از نسخه محلی استفاده کنید. اگر نه، به فضای نام بالاتر بروید.
- محصور، دوم : اگر تابع فعلی در یک تابع دیگر محصور شده است، نام آن را در آن تابع خارجی جستجو کنید. اگر نه، به فضای نام بالاتر بروید.
- جهانی، سوم : به دنبال نام در اشیاء تعریف شده در فضای نام جهانی بگردید
- ساخته شده، آخرین : در نهایت، متغیر را در میان نامهای داخلی پایتون جستجو کنید.
اگر مفسر تمام 4 مرحله را طی کند و نام را پیدا نکند، الف NameError
مطرح می شود، البته اگر عملیات یک عملیات انتساب نباشد، در این صورت به جای بالا بردن خطا، یک شی با آن نام در محدوده محلی ایجاد می شود.
مثال:
x = 200
def demo():
x = 300
def inner():
print(x)
inner()
demo()
//300
در مورد فوق در فراخوان چاپx
، مفسر نمی تواند یک شی با نام پیدا کند x
در تابع inner
دامنه، به سمت خارج به سمت تابع محصور حرکت می کند که در این صورت یک را پیدا می کند'x'
با ارزش 300
به این ترتیب جستجو خاتمه می یابد. اگر هنوز یک شی با نام 'x'
در تابع محصور کننده قرار نداشت 'demo'
، جهانیx
با ارزش 200
برگردانده می شد
مثال های بیشتر:
x = 500
def demo():
print(x)
x = 300
print(x)
demo()
//500
//300
def demo2():
y = 400
def inner():
print(x + y)
inner()
demo2()
//900
بیانیه جهانی
این global
دستور تنها چیزی است که می تواند نام تعریف شده در داخل یک تابع را به یک نام جهانی تبدیل کند. این به این معنی است که نام دقیقاً مانند نامهایی که در فضای نام جهانی تعریف شده است رفتار میکند و از هر نقطه برنامه قابل دسترسی خواهد بود.
مثال ها:
def demo():
global x
x = 200
demo()
print(x)
//200
اگر یک نام سراسری مشابه نام مشخص شده در عبارت جهانی وجود داشته باشد، هر گونه تغییری که در شیئی که شناسایی می کند انجام شود در سطح جهانی اعمال می شود. مثال ها:
x = 100
def demo():
global x
x = 500
demo()
print(x)
//500
برای اعلام چندین نام سراسری در یک عبارت جهانی، از کلمه کلیدی جهانی و به دنبال آن نام های جدا شده با کاما استفاده می کنیم، به عنوان مثال:
def demo():
global x, y, z
x = 4
y = 3
z = x + y
demo()
print(x, y, z)
//4, 3, 7
در حالی که دستور جهانی می تواند گاهی مفید باشد، می تواند کد را مبهم کند زیرا می تواند ردیابی نام های جهانی را دشوار کند. بنابراین، باید تا حد امکان از آن اجتناب شود، زیرا همه نامهای داخل یک تابع به طور پیشفرض محلی برای آن تابع هستند، زیرا بهترین سیاست است. در عوض میتوانیم مقادیر سراسری را بهعنوان آرگومانهای تابع ارسال کنیم و سپس مقادیر اصلاحشده را برگردانیم.
بیانیه غیر محلی
این nonlocal
بیانیه پسر عموی نزدیک است global
بیانیه. در حالی که global
بیانیه نامی را در سطح جهانی در دسترس قرار می دهد nonlocal
بیانیه یک نام را در دسترس قرار می دهد محدوده تابع را در بر می گیرد. این همچنین به تابع تودرتو اجازه می دهد تا تغییراتی در متغیرهای تعریف شده در تابع محصور ایجاد کند. مثال ها:
def demo():
x = 400
def inner():
nonlocal x
x = 600
inner()
print(x)
demo()
//600
def demo2():
def inner():
nonlocal y
y = 500
inner()
print(y)
demo2()
//500
توجه: ما نمی توانیم از آن استفاده کنیم nonlocal
بیانیه ای با یک تابع سطح بالا، امتحان کردن این امر باعث افزایش a می شود SyntaxError
def demo():
nonlocal y
y = 100
demo()
//SyntaxError: no binding for nonlocal 'y' found