-
Python: Generators
Generator is for lazy iteration. Using yield in a function makes it a generator. Like async function, calling a generator does not execute the code. While executing an async function requires say asyncio.run(), a generator executes when it is iterated on say with next(). Normally a generator is consumed by a for loop. finally block in…
-
Python: Decorators
Wrap to alter or enhance the object being wrapped. Like: Function metadata like doc string is now hidden for the wrapped function square. Best practice: @wraps() decorator from functools copies function metadata into the replacement function. When there are multiple decorators, the order might matter: For example: A decorator can accept arguments. The temp above…
-
Python: Anonymous function
Multiple statements or nonexpression statements like try or while cannot appear in lambda expression. If free variables (not specified as parameters) are used in a lambda, the value of the variable is not the one when the lambda was defined, instead the value at the time of lambda evaluation is used (late binding). To capture…
-
Python: Function Scope
On each call to a function a local namespace is created which includes the names of the function arguments and the variables locally assigned within the function. Other variables accessed in the function belong to (enclosing) global namespace. The method globals() returns the dict __globals__ which is the global namespace. The method locals() concocts and…
-
Python: Function parameters
Default arguments Default parameter values are evaluated once when the function is defined, not on each call. Best practice: Variadic arguments Below function accept variable number of arguments. All extra arguments are placed in rest variable as a tuple. Keyword arguments Below, debug variable must be supplied as keyword argument like read_data(‘foo.txt’, debug=True). Variadic keyword…
-
Python: Protocols
Python interpreter recognizes special methods like __method__() and invokes them in hard-wired situations. A group of related such “dunder” or “double underscore” methods are called a protocol. An object that implements a protocol, can be used in idiomatic ways. Object Protocol About object creation, initialization, destruction, and representation. x = SomeClass(args) is translated into: It…
-
Python: Objects
All data in a Python program are objects. An object has: identity, type, and value. Type is also object. Data and methods are an object’s attributes. Even an operator like a + 10 is mapped to a method a.__add__(10) and thus is an attribute. Assigning object creates reference. Shallow copy of a container object creates…
-
Python: GIL
GIL or Global Interpreter Lock is an implementation details of CPython. Reference counting is how CPython implements automatic garbage collection. With multiple threads, synchronization is required for correct reference counting. CPython takes a process-wide lock and that is GIL. Consequently, with CPython, for a single process, only one Python byte-code (by a thread) can execute…
-
Python: Synchornization
All synchronization primitives are available from threading and multiprocessing modules. A primitive from threading module synchronizes between threads from the same process. A primitive from multiprocessing module synchronizes between threads across multiples processes and is heavier. Primitives: