Python has names and references
Python object modelAn assignment statement creates a symbolic name that you can use to reference an object. The statement x = 'foo' creates a symbolic name x that refers to the string object 'foo'.
LEGB
Namespace = declarative region that provides a scope to the identifiers. Collection of currently defined symbolic names along with information about the object that each name references.
- Local =
locals()returns dict(), returns copy of local namespace - Enclosing
nonlocal a- Global =
globals()returns dict(), returns reference to object global a- Built-In namespace =
dir(__builtins__)
Examples
def fоo():
return total + 1
total = 0
print(foo()) # 1 dеf f():
s = "I love London!"
рrint(s)
s = "I love Paris!"
f()
рrint(s)
# I love London!
# I love Paris!
========================================================================
def f():
print(s)
s = "I love London!"
print(s)
s = "I love Paris!"
f()
# UnboundLocalError: local variable 's' referenced before assignmentdef nwe():
b = (2, 4)
print(locals()['b'])
locals()['b'] += (4,)
print(locals())
print(b)
nwe()
# (2, 4)
# {'b': (2, 4)}
# (2, 4)
# WHY? locals() inside a function is a snapshot, not the real thing.
# if you use += for tuple it will work, but different object will be created
dir(), vars()
- Use
dir(x)when you want a quick list of everything an object can do (including inherited methods, class attributes, and__slots__). - Use
vars(x)when you need a dictionary of key-value pairs for an object's instance state (its actual stored data). - Use
inspectmodule when you need deep metadata (e.g., source code, function signatures, or exact type hints). - Use
hasattr()/getattr()when you want to dynamically check or access an attribute using a string variable. vars()- Python objects usually store their instance variables in a dictionary that belongs to the object (except for slots).
vars(x)returns this dictionary (as doesx.__dict__) - if vars() is without argument then it returns locals()
vars(obj)simply retrievesobj.__dict__dir()dir(obj)implicitly callsobj.__dir__()if defineddir(__builtins__)- dir returns slots, while vars doesn’t
- displays class attributes as well
dir(x), returns a dictionary ofx's "attributes, its class's attributes, and recursively the attributes of its class's base classes."