इस chapter में हम Python में Scope of Objects & Modules के बारे में जानेंगे — जिसमें शामिल है LEGB Rule (Local, Enclosing, Global, Built-in), Modules & Namespaces, Import model और Reloading modules। ये concepts large programs को organized रखने में मदद करते हैं।
जब हम Python में कोई variable या function बनाते हैं, तो वो किसी न किसी scope में exist करता है। Scope का मतलब है — variable कहां तक accessible है और कहां नहीं। यह concept program की memory management और variable lifetime को समझने के लिए बहुत ज़रूरी है।
Scope वह area है जहाँ कोई variable या object valid रहता है और use किया जा सकता है। Python में हर variable का एक lifetime और एक scope होता है।
x = 10 # Global variable
def show():
y = 20 # Local variable
print("Inside function:", y)
show()
print("Outside function:", x)
Output:
Inside function: 20
Outside function: 10
💡 Explanation:
- x global scope में है — function के बाहर।
- y local scope में है — सिर्फ function के अंदर accessible है।
Python में 4 main scopes होते हैं, जिन्हें collectively कहा जाता है — LEGB Rule (Local, Enclosing, Global, Built-in)
| Scope Type | Description |
|---|---|
| Local (L) | Function के अंदर defined variables |
| Enclosing (E) | Nested functions (outer function का scope) |
| Global (G) | Module level (पूरे file में accessible) |
| Built-in (B) | Python predefined names (जैसे len(), print()) |
Function के अंदर defined variables सिर्फ उसी function तक limited होते हैं।
def local_example():
x = 5 # Local variable
print("Inside function:", x)
local_example()
print(x) # Error: x is not defined
Output:
Inside function: 5
NameError: name 'x' is not defined
Function के बाहर defined variables को global कहा जाता है। इन्हें पूरे program में access किया जा सकता है।
x = 100 # Global variable
def show():
print("Inside function:", x)
show()
print("Outside function:", x)
Output:
Inside function: 100
Outside function: 100
अगर आप function के अंदर किसी global variable को modify करना चाहते हैं, तो global keyword का इस्तेमाल करना होगा।
x = 50
def update():
global x
x = 200 # Modify global variable
print("Inside function:", x)
update()
print("Outside function:", x)
Output:
Inside function: 200
Outside function: 200
💡 Explanation: global x ने function को बताया कि x एक global variable है, local नहीं।
Nested functions में outer function का variable inner function के लिए accessible होता है। लेकिन inner से directly modify नहीं किया जा सकता।
def outer():
x = "outer variable"
def inner():
print("Accessing from inner:", x)
inner()
outer()
Output:
Accessing from inner: outer variable
अगर inner function को outer function के variable को modify करना हो, तो nonlocal keyword use किया जाता है।
def outer():
x = "outer variable"
def inner():
nonlocal x
x = "modified by inner"
print("Inner:", x)
inner()
print("Outer:", x)
outer()
Output:
Inner: modified by inner
Outer: modified by inner
Python के कुछ names हमेशा globally available रहते हैं, जैसे len(), print(), type() आदि।
इन्हें Built-in scope कहा जाता है।
print(len("Python")) # Built-in function
print(type(10))
Output:
6
<class 'int'>
x = 10
def test():
x = 20
print("Inside function:", x)
test()
print("Outside function:", x)
Output:
Inside function: 20
Outside function: 10
💡 Function के अंदर वाला x local है और बाहर वाला global — दोनों अलग-अलग memory locations पर रहते हैं।
किसी variable का lifetime तब शुरू होता है जब उसे memory में create किया जाता है, और तब खत्म होता है जब function समाप्त होता है या variable delete हो जाता है।
def show():
x = 100
print("Inside function:", x)
show()
print("Outside:", x) # Error: x not defined
Output:
Inside function: 100
NameError: name 'x' is not defined
💡 Variable x function खत्म होते ही memory से delete हो गया।
Python में जब भी आप किसी variable या function का नाम use करते हैं, तो Python interpreter उस नाम को ढूँढने के लिए एक fixed order follow करता है। इसी को कहा जाता है LEGB Rule — यानी Local → Enclosing → Global → Built-in.
👉 यह rule बताता है कि किसी variable को Python कहाँ-कहाँ search करेगा और कौन-सा value return करेगा।
| Scope | Description |
|---|---|
| L - Local | Function या block के अंदर defined variables |
| E - Enclosing | Nested (inner) function के बाहर वाले function का scope |
| G - Global | Module या script के top-level variables |
| B - Built-in | Python predefined names जैसे len(), print(), range() |
Python इसी order में variable को ढूँढता है — Local → Enclosing → Global → Built-in अगर किसी scope में variable नहीं मिला, तो अगले scope में search करता है।
x = "Global X"
def outer():
x = "Enclosing X"
def inner():
x = "Local X"
print(x) # Which X?
inner()
outer()
Output:
Local X
💡 Explanation: - Python पहले inner function के Local variable में x ढूँढता है। - मिला तो वहीं से value ले लेता है, इसलिए output “Local X” है।
def outer():
message = "Hello from outer"
def inner():
print(message) # Enclosing variable
inner()
outer()
Output:
Hello from outer
💡 यहां message Local में नहीं मिला, इसलिए Python ने उसे Enclosing scope (outer function) में खोज लिया।
x = 10 # Global
def modify():
global x
x = 25 # modifies global variable
modify()
print("After modification:", x)
Output:
After modification: 25
💡 Without global keyword, x local variable माना जाता और global variable change नहीं होता।
nonlocal keyword nested functions में outer variable को modify करने के लिए use होता है।
def outer():
x = "outer value"
def inner():
nonlocal x
x = "changed by inner"
print("Inner:", x)
inner()
print("Outer:", x)
outer()
Output:
Inner: changed by inner
Outer: changed by inner
💡 inner function ने nonlocal keyword से outer scope का variable modify किया।
print(len("Python")) # Built-in function
print(max([2, 4, 8, 1]))
Output:
6
8
💡 Built-in scope हमेशा accessible रहता है।
इसे import builtins करके explore किया जा सकता है।
x = "global x"
def outer():
x = "enclosing x"
def inner():
x = "local x"
print("Inner:", x)
inner()
print("Outer:", x)
outer()
print("Global:", x)
Output:
Inner: local x
Outer: enclosing x
Global: global x
💡 हर scope का अपना independent variable है। Python nearest scope से value उठाता है।
Python में आप variables को programmatically check कर सकते हैं कि कौन से global हैं और कौन से local।
x = 100
def func():
y = 200
print("Local scope:", locals())
print("Global scope:", globals().keys())
func()
Output:
Local scope: {'y': 200}
Global scope: dict_keys([... , 'x', 'func'])
💡 locals() function current scope के variables return करता है।
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print("LEGB:", x)
inner()
outer()
Output:
LEGB: local
💡 Python ने सबसे पहले local scope में variable पाया, इसलिए वहीं से value लिया और बाकी scopes को check नहीं किया।
globals() function.NameError.Python में module का मतलब है — एक file जिसमें Python code (functions, variables, classes) लिखा गया हो ताकि उसे दूसरे programs में reuse किया जा सके। Module हमें code को logically divide करने की सुविधा देता है।
हर Python file (.py) खुद में एक module होती है।
Example: अगर आपके पास math_utils.py नाम की file है, तो वह एक module है।
एक module simply एक .py file होती है जिसमें functions, variables, constants, classes वगैरह define किए जा सकते हैं। Modules code reuse और modular programming को support करते हैं।
# mymodule.py
def greet(name):
print("Hello,", name)
x = 100
अब हम इस module को किसी दूसरे program में import करके use कर सकते हैं।
किसी module को use करने के लिए Python में import statement का इस्तेमाल किया जाता है।
# main.py
import mymodule
mymodule.greet("Ravi")
print("Value of x:", mymodule.x)
Output:
Hello, Ravi
Value of x: 100
💡 Explanation:
import mymodule पूरी file को current program में लाता है।
Functions या variables को use करने के लिए mymodule. prefix देना पड़ता है।
import mymodule as mm
mm.greet("Anita")
print(mm.x)
💡 यहां हमने mymodule को छोटा नाम mm दे दिया। यह large modules के लिए convenient होता है।
from mymodule import greet, x
greet("Karan")
print(x)
💡 इससे आप पूरे module को नहीं, सिर्फ selected members को import करते हैं।
from mymodule import *
greet("Meena")
print(x)
💡 Caution: यह तरीका recommended नहीं है क्योंकि इससे namespace में conflicts हो सकते हैं।
Python के साथ कई ready-made modules आते हैं जिन्हें हम directly import कर सकते हैं:
import math
print(math.sqrt(25))
print(math.pi)
Output:
5.0
3.141592653589793
import math
print(math.__file__)
💡 यह बताता है कि Python module कहां installed है (built-in modules में path नहीं दिखेगा)।
जब आप कोई module import करते हैं, Python उसे इस order में ढूँढता है:
import sys
print(sys.path)
💡 sys.path एक list होती है जिसमें Python modules search करने के लिए paths store करता है।
# mymath.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
main.py:
import mymath
print(mymath.add(10, 5))
print(mymath.subtract(10, 5))
Output:
15
5
Python में हर module में एक special variable होता है: __name__ अगर module को directly run किया गया है, तो इसका value __main__ होता है। लेकिन अगर किसी दूसरे file में import किया गया है, तो इसका नाम module का नाम होता है।
# demo_module.py
def show():
print("Inside demo module")
if __name__ == "__main__":
print("Running directly")
else:
print("Imported as module")
Output:
Running directly (जब file direct run की जाती है)
Imported as module (जब किसी दूसरे file में import किया जाता है)
import module_name.from module_name import function_namePython में हर module एक namespace की तरह काम करता है। जब हम कोई module import करते हैं, तो Python internally उसके लिए एक symbol table (namespace) बनाता है जहाँ उसके सारे variables, functions, classes store होते हैं।
इस तरह से दो अलग-अलग modules में same नाम के variables भी बिना conflict के exist कर सकते हैं।
Namespace एक logical area है जहाँ Python किसी variable या object का नाम और उसकी value map करके रखता है। इसे आप एक dictionary की तरह समझ सकते हैं जहाँ:
name --> object reference
Python में चार मुख्य प्रकार के namespaces होते हैं:
जब आप कोई module import करते हैं, Python उस module के लिए एक namespace object बनाता है। Module में मौजूद हर function, class या variable इस namespace का हिस्सा होता है।
# file: mymodule.py
x = 10
def display():
print("Inside mymodule")
# file: main.py
import mymodule
print(mymodule.x)
mymodule.display()
Output:
10
Inside mymodule
💡 Explanation:
- जब import mymodule किया गया, Python ने mymodule नाम से namespace create किया।
- अब module के अंदर की सभी चीज़ें इसी namespace के अंदर accessible हैं।
किसी भी module का namespace Python में एक dictionary के रूप में represent होता है,
जिसे आप __dict__ attribute से देख सकते हैं।
import math
print(math.__dict__.keys())
💡 यह सभी members (functions, constants, classes) की list देता है।
हर module का अपना global namespace होता है। इसलिए दो अलग-अलग modules में same नाम के variables होने पर कोई problem नहीं होती।
# file: mod1.py
x = 10
# file: mod2.py
x = 50
# file: main.py
import mod1
import mod2
print(mod1.x)
print(mod2.x)
Output:
10
50
💡 दोनों modules का अपना independent namespace है, इसलिए कोई conflict नहीं हुआ।
dir() function किसी namespace के अंदर defined सभी names की list देता है।
import math
print(dir(math))
💡 यह math module में मौजूद सभी functions और constants को दिखाएगा।
# file: greet1.py
def hello():
print("Hello from greet1")
# file: greet2.py
def hello():
print("Hello from greet2")
# file: main.py
import greet1, greet2
greet1.hello()
greet2.hello()
Output:
Hello from greet1
Hello from greet2
💡 यहां दोनों files में same function name है, लेकिन कोई conflict नहीं हुआ क्योंकि हर module का अपना namespace है।
अगर आप किसी module में बदलाव करते हैं और उसे दोबारा reload करना चाहते हैं
(बिना Python को restart किए), तो importlib.reload() का use करते हैं।
import importlib
import mymodule
# ... make changes in mymodule.py file ...
importlib.reload(mymodule)
💡 यह module को memory से remove करके दोबारा load करता है और उसका namespace refresh हो जाता है।
जब module directly run किया जाता है, उसका __name__ variable “__main__” set होता है। लेकिन जब उसे किसी दूसरे file में import किया जाता है, तो उसका __name__ module के नाम के बराबर होता है।
# file: demo.py
print("Module name:", __name__)
💡 अगर आप इसे सीधे चलाएँगे तो output होगा — Module name: __main__
और import करने पर — Module name: demo
आप किसी module के namespace को dynamically explore भी कर सकते हैं।
import math
for name in dir(math):
if not name.startswith("__"):
print(name)
💡 यह math module के सारे publicly available names दिखाएगा।
dir(module_name).importlib.reload(module).
जब हम Python में import statement लिखते हैं, तो Python एक detailed internal process follow करता है
module को ढूंढने, compile करने, और memory में load करने के लिए।
इस पूरी प्रक्रिया को कहा जाता है — Python Import System या Import Model।
Python में जब आप लिखते हैं:
import math
तब internally ये steps execute होते हैं:
जब आप कोई module import करते हैं, Python उसे नीचे दिए गए order में ढूँढता है:
import sys
for path in sys.path:
print(path)
💡 sys.path list Python के search directories दिखाती है। आप इसमें custom path भी जोड़ सकते हैं:
sys.path.append("C:/MyModules")
अब Python वहाँ भी modules को search करेगा।
Python internally एक dictionary maintain करता है जिसे sys.modules कहा जाता है। इसमें वो सभी modules stored रहते हैं जो memory में already loaded हैं।
import sys
import math
print("math" in sys.modules)
Output:
True
💡 अगर module पहले से loaded है, Python उसे दोबारा load नहीं करता। इस वजह से imports fast होते हैं।
जब कोई Python module पहली बार import होता है,
Python उसे compile करके .pyc file में बदल देता है (bytecode form)।
यह file __pycache__ folder में store होती है।
अगली बार वही module import करने पर Python compiled version (.pyc) directly load कर लेता है, जिससे performance बढ़ जाती है।
अगर module में runtime पर changes किए गए हैं और आप उन्हें reload करना चाहते हैं, तो importlib.reload() function use कर सकते हैं।
import mymodule
import importlib
# make changes in mymodule.py
importlib.reload(mymodule)
💡 इससे updated code memory में reload हो जाता है।
from math import sqrt, pi
print(sqrt(16))
print(pi)
💡 यह तरीका पूरे module को नहीं, सिर्फ selected members को import करता है।
Import Process flow को समझने के लिए नीचे diagram देखें 👇
+----------------------------+
| import module statement |
+-------------+--------------+
|
v
Is module in sys.modules?
|
+------v-------+
| Yes -> Use it |
+-------------------+
|
+------v-------+
| No -> Search sys.path |
+------v-------+
|
+------v-------+
| Found? Compile .py -> .pyc |
| Load into memory & sys.modules |
+-------------------+
अगर Python को module नहीं मिलता, तो ModuleNotFoundError raise होती है। आप try-except block में handle कर सकते हैं।
try:
import unknown_module
except ModuleNotFoundError:
print("Module not found!")
Output:
Module not found!
आप किसी module के location या availability को check करने के लिए importlib.util.find_spec() का use कर सकते हैं।
import importlib.util
spec = importlib.util.find_spec("math")
print(spec.origin)
💡 यह module की actual file location बताता है।
import sys
sys.path.append("C:/Users/Anita/MyModules")
import mycustom
mycustom.greet()
💡 इससे Python user-defined folder में भी modules को search करेगा।
importlib.reload(module_name).__pycache__ folder as .pyc files.ModuleNotFoundError.Python में जब कोई module पहली बार import होता है, तो वो memory में load होकर sys.modules dictionary में store हो जाता है। उसके बाद अगर आप उसी module को दोबारा import करते हैं, तो Python उसे memory से ही load कर देता है — file को दोबारा read नहीं करता।
लेकिन कई बार development या testing के दौरान आपको किसी module में changes करने के बाद updated version reload करने की जरूरत होती है — ऐसे में importlib.reload() काम आता है।
Normal import statement दोबारा module को reload नहीं करता क्योंकि module पहले से sys.modules में मौजूद होता है।
import mymodule
import mymodule # second import doesn’t reload it
💡 ऊपर के दोनों imports में Python mymodule.py को सिर्फ पहली बार load करेगा।
Python का importlib module हमें किसी already loaded module को reload करने की सुविधा देता है। Syntax होता है:
import importlib
import module_name
importlib.reload(module_name)
💡 यह module को memory से remove करके दोबारा load करता है, ताकि updated code तुरंत reflect हो जाए।
मान लीजिए हमारे पास mymodule.py file है:
# mymodule.py
def greet():
print("Hello from Version 1")
अब main program:
import mymodule
mymodule.greet()
# अब आपने mymodule.py में बदलाव किया:
# def greet():
# print("Hello from Version 2")
import importlib
importlib.reload(mymodule)
mymodule.greet()
Output:
Hello from Version 1
Hello from Version 2
💡 यहां importlib.reload() ने module का नया version memory में reload कर दिया।
जब आप importlib.reload() call करते हैं, तो Python internally module को
sys.modules से temporarily remove करके file system से दोबारा load करता है।
Reloaded module का namespace reset हो जाता है, इसलिए पुरानी values या objects overwrite हो सकते हैं।
import sys, importlib
import mymodule
print("Before reload:", sys.modules["mymodule"])
importlib.reload(mymodule)
print("After reload:", sys.modules["mymodule"])
Reloading सिर्फ custom modules के लिए नहीं, बल्कि built-in या third-party modules के लिए भी किया जा सकता है (though rare)।
import importlib
import math
importlib.reload(math)
print("Math module reloaded successfully!")
💡 यह mostly debugging या plugin systems में use होता है।
आप किसी module के loaded होने से पहले verify कर सकते हैं:
import sys
if "mymodule" in sys.modules:
print("Module is already loaded")
else:
print("Module not loaded yet")
💡 इससे आप unnecessary reload से बच सकते हैं।
Jupyter Notebook, IDLE या Shell जैसे environments में module reload करना common है, ताकि हर बार kernel restart न करना पड़े।
import mymodule
from importlib import reload
reload(mymodule)
💡 इसका उपयोग especially live code testing और teaching environments में होता है।
importlibimportlib.reload(module_name)sys.modules.