স্কোপ মানে আপনার কোডের কোথা থেকে একটি ভ্যারিয়েবল দেখা আর ব্যবহার করা যায় — প্রোগ্রামিং পরিচিতি-তে শেখা একই ধারণা, Python-নির্দিষ্ট একটি অর্থবহ মোচড়সহ।
একটি ফাংশনের ভেতরে তৈরি হওয়া ভ্যারিয়েবল শুধু সেই ফাংশনের ভেতরেই থাকে:
def set_name():
name = "Priya" # local to set_name()
print(name) # works fine here
set_name()
# print(name) # NameError — name doesn't exist out hereএকটি Python ফাংশন কোনো বিশেষ কীওয়ার্ড ছাড়াই একটি গ্লোবাল ভ্যারিয়েবল পড়তে পারে — কোনো import বা ঘোষণার দরকার নেই। global কীওয়ার্ড শুধু তখনই দরকার যখন আপনি একটি পুনরায় assign করতে চান, শুধু পড়তে নয়:
site_name = "Learn Computer Academy"
def show_name():
print(site_name) # works — reading a global needs nothing special
show_name()একটি ফাংশনের ভেতরে একটি নামে assign করলে Python ডিফল্টভাবে সেটাকে লোকাল হিসেবে গণ্য করে — এমনকি একই নামের একটি গ্লোবাল থাকলেও। এটা override করে আসল গ্লোবাল ভ্যারিয়েবলে পুনরায় assign করতে global দরকার:
count = 0
def increment_broken():
count = count + 1 # UnboundLocalError — count is treated as local here,
# and it hasn't been assigned yet at this point
def increment():
global count
count = count + 1 # now this correctly modifies the global
increment()
print(count) # 1global-এর বদলে প্যারামিটার প্রাধান্য দিন
পুরো একটি কোডবেসে global-এর উপর নির্ভর করলে একটি মান আসলে কোথা থেকে আসছে তা খুঁজে বের করা কঠিন হয়ে যায়। পরিষ্কার, বেশি প্রচলিত প্যাটার্ন হলো মানটিকে একটি প্যারামিটার হিসেবে পাস করা আর নতুন মান রিটার্ন করা, সরাসরি একটি গ্লোবাল পরিবর্তন করার বদলে।
কিছু ভাষা থেকে আরেকটি আসল পার্থক্য: Python-এ একটি if বা for ব্লকের ভেতরে তৈরি হওয়া একটি ভ্যারিয়েবল সেই ব্লকে সীমাবদ্ধ নয় — এটি ঘিরে থাকা ফাংশনের বাকি অংশের জন্য দৃশ্যমান:
def check(n):
if n > 0:
result = "positive"
print(result) # this works even outside the if block, as long as n > 0 ran
check(5) # "positive"আরেকটি ফাংশনের ভেতরে সংজ্ঞায়িত একটি ফাংশন স্বয়ংক্রিয়ভাবে তার ঘিরে থাকা ফাংশনের ভ্যারিয়েবল পড়তে পারে — একটি গ্লোবাল পড়ার একই নিয়ম। একটিতে পুনরায় assign করতে, nonlocal সরাসরি গ্লোবাল স্কোপে না গিয়ে এক লেভেল উপরে global-এর সমতুল্য:
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2 — count is remembered between callsএই প্যাটার্ন — একটি ফাংশন আরেকটি ফাংশন রিটার্ন করছে যা state মনে রাখে — একে বলা হয় একটি closure। এটি সত্যিকারভাবে দরকারি একটি কৌশল, কিন্তু একটি নিশ কৌশল; বুঝতে আরেকবার পড়তে হলে চিন্তা করবেন না।