- iterable ~~
IEnumerable
- range ~~
IEnumerable{int}
- Slicing
- creates shallow copy (i.e. references are copied, not underlying objects)
- notation =
object[{start index}:{end index (noninclusive)}]
for
~~for
- Behind the scenes,
for
callsiter()
on the collection to get the iterator, which defines the__next__
method.
- Behind the scenes,
pass
is no-opraise
~~throw
else
- if this is for an
if
-block, then it's pretty standard behavior - on a
try
-block, it is executed if there were no exceptions raised. - on a
for
-loop, it is executed at the end condition, iff there was nobreak
,continue
orreturn
hit.
- if this is for an
with
~~using
- Default values don't have to be compile-time constants, but are bound at point of function definition!
- e.g.
i = 5 def myFunc(arg = i): print(arg) i = 6 myFunc() # prints 5, not 6
- e.g.
in
~~IEnumerable{T}.Contains
- e.g.
x = input("Please enter the value") if x in ('helloworld', 'hello', 'world'): print("Hello World")
- e.g.
*
and**
- On the call-site,
*
can be used to unpack a list/tuple to a function call's arguments. e.g.def func(a = 1, b = 2): pass args = [3, 4] func(*args)
**
can be used to unpack a dictionary to a function call's arguments. e.g.def func(a = 1, b = 2): pass args = {'a': 3, 'b': 4} func(**args)
- On the function-definition site,
*
~~params object[]
for variadic args. e.g.def func(a, *args)
**
is special variadic args: all the named/keyword args that aren't a formal parameter. e.g.def func(a, **keywordArgs, b = 5): pass func(6, b = 7, c = "Something", d = "Another thing") # keywordArgs will be a dictionary containing c and d, but not a, b
- On the call-site,
- Lambda expressions:
- Syntactically limited to single expression (so ~~
=>
) - e.g.
from typing import Callable def lambdaInput(n: int, arg: Callable[[int], int]) -> int: return arg(n) + 5 lambdaRes = lambdaInput(5, lambda x: x + 5) def lambdaOutput(n: int) -> Callable[[str], int]: return lambda s: len(s) + n lambdaFunc = lambdaOutput(n=5) lambdaRes = lambdaFunc("HelloWorld")
- Syntactically limited to single expression (so ~~
deque
- data structure with efficient appendLeft and pop from both ends.from collections import deque queue = deque(['A', 'B', 'C']) queue.append('D') queue.popleft() # yields A
map(lambda, iterable)
~~IEnumerable{T}.Select(lambda)
import {module}
~~using {namespace}
dir
lists the exports of a module (e.g.dir(sys)
)__init__.py
is used to define a directory as a package- A package can have subpackages (recursively)
- Can define
__all__
in the__init__.py
to determine what to import whenfrom {package} import *
is used. - Within a package, one can use either absolute package identifier or relative paths from current module to reference other submodules or sub-packages.
- JSON serialization/deserialization can be done using the
json
module:import json json.dumps({'Good': 23, 'bye': 42, 'NewtonSoft': 111}) x = [1, 2, 3, 4, 5] json.dump(x, file) y = json.load(file)
- Metaclass - the class of a class. Class definitions incorporate class name, class dictionary (for methods and fields), and base classes. A class is an instance of a metaclass, just like an object is an instance of a class. The default metaclass is
type
. class
:- Syntax is:
class BaseClass1: pass class BaseClass2: pass class DerivedClass(BaseClass1, BaseClass2): staticVar = 'static class field' def __init__(self): self.memberVar = 'instance field' def method(self): pass classInstance = DerivedClass()
- All methods are effectively virtual
isinstance(obj, type)
~~obj is type
issubclass(t1, t2)
tests ift1
is a subclass (i.e. derivative) oft2
super
let's you avoid referring to the base class explicitly- Method Resolution Order (MRO) changes dynamically to support cooperative calls to
super
(call-next-method approach)- MRO documentation
- While there is no support for private fields in Python, prefixing methods/fields with '__' results in name mangling (to become _classname__var):
class C: __privateVar = 5 # compiler replaces this with _C__privateVar
- Can be equivalent to
struct
:class Struct: pass s = Struct() s.a = 42 s.b = 'Another field'
- Note that this approach can be used more generally by defining
read
andreadline
methods in thestruct
-like class, which parse strings into fields
- Note that this approach can be used more generally by defining
- Can implement
__iter__
and__next__
methods to become an iterable collection- Alternatively, and sometimes more advisably, generator functions can be used to the same effect without needing to implement the iterator tracking (simply use
yield
). e.g.def reverse(data): for index in range(len(data) - 1, -1): yield data[index] for char in reverse('golf'): print(char)
- Alternatively, and sometimes more advisably, generator functions can be used to the same effect without needing to implement the iterator tracking (simply use
- Syntax is:
- Parallelism:
threading
- contains synchronization primitives (locks, semaphores,Threading
base class).- It is recommended to have resources allocated by a single thread, which has a
Queue
that receives requests for those resources from the other threads. This way the concurrency can be designed in a thread-safe manner with simplicity
- It is recommended to have resources allocated by a single thread, which has a
asyncio
- Performance measurements:
profile
pstats
timeit
- Logging
logging
- Unit testing:
doctest
- embeds tests/expected result in the method's docstring, and scans the module to run all such testsunittest
- more traditional unit-testing module which can be used to implement test classes
- Garbage collection:
gc
weakref
- allows tracking objects without creating references to them
- Package management (seealso):
- In order to prevent cross-pollination of conflicting package dependencies between different Python applications, each application can have a virtual environment.
> py -3 -m venv <virtual environment folder> > <virtual environment folder>\scripts\activate
- https://pypi.org - Python Package Index (default location where packages are installed from by
pip
) - To install packages:
> python -m pip install <package name>
- In order to prevent cross-pollination of conflicting package dependencies between different Python applications, each application can have a virtual environment.
PYTHON_STARTUP
environment variable can be used to point to a file that defines a set of commands to run on startup (interactive mode only)usercustomize
andsitecustomize
are hooks that can be used to execute code on every invocation of Python (more information here)