Python
Python is a dynamically-typed, interpreted programming language. It has gained widespread use due to its resemblance to pseudo-code and numerous libraries.
Python Package Manager
Pip Installs Packages (pip):
pip
is the most widely used package manager for Python.- Comes pre-installed with Python >3.4
- Installs packages from the Python Package Index (PyPI)
- Usage
pip install package_name
pip uninstall package_name
pip list
pip install --upgrade package_name
virtualenv:
virtualenv
is a tool for creating isolated Python environments.- Allows managing of dependencies for projects separately
- Usage:
virtualenv env_name
source env_name/bin/activate
(Activate virtual environment)
pipenv:
pipenv
combinespip
andvirtualenv
- Uses a Pipfile to specify dependencies and a Pipfile.lock for version locking.
- Usage:
pipenv install
pipenv install package_name
pipenv uninstall package_name
pipenv shell
(Activate virtual environment)
uv:
- Fast Python package manager and resolver
- Drop-in replacement for
pip
,pip-tools
,virtualenv
- handles virtual environments natively
- Single binary written in Rust
- unified CLI for tasks like
uv pip install
,uv venv
, oruv python
- Manages projects with a
pyproject.toml
file uvx
(alias foruv tool run
) for executing scripts in isolated environment
Compiling Python
Python by default is not compiled to an executable nor JIT-compiled to machine code. Instead, the standard interpreter CPython compiles a given python script to bytecode that can be run line-by-line by the Python Virtual Machine (PVM).
To compile Python to bytecode:
python -m py_compile source.py
The compiled bytecode will be in the __pycache__
directory. To execute it from
the command line:
python -m source
However, there are tools to compile python code.
Cython:
- translates Python code to C/C++ code
- supports calling C functions and declaring C types
PyPy
- Python implementation with a JIT compiler.
- Runtime optimisations, fully language compliant
- Can run most Python code, except for CPython extensions
- PyPy's meta-tracing toolchain is called RPython.
- Uses meta-tracing: takes interpreter as input and produces a tracing just-in-time compiler as output.
Type Checking in Python
Python supports type hinting since version 3.5:
import typing # primitive type hints def add(a: int, b: int) -> int: return a + b x : int = add(4,5) print(x) # type hints for lists (or tuples, dicts) def get_floats(input : list[float]) -> list[float]: floats : list[float] = [3.4, 2.8, 2.5, 3.9] result = [input[i] + floats[i] for i in range(len(input))] return result print(get_floats([3.5,2.8,3.1])) # union type hints (allow more than one type) def sum_ab(a: int | float, b: int | float) -> int | float: return a + b
Python will not check the types by default. Instead, the types can be statically
checked before running the program by a tool like mypy
:
mypy source.py
Fundamentals
Object:
- Everything in Python is an object
- Including integers, strings, lists, functions, classes and class instances
Attributes:
- An attribute is a value associated with an object
- Instance Attributes are specific to an instance of a class.
- Class Attributes are shared among all instances (static variables)
- Module Attributes are defined at the top level
Syntax
my_list = [1, 2, 3] # declaring list syntax my_dict = {'key': 'value'} # declaring dict syntax # unpack/unwrap operator def add(a, b, c): return a + b + c iterables = [1,2,3] print(add(*iterables)) # same as add(1,2,3) # list comprehensions squares = [x**2 for x in range(4)] # = [0,1,4,9] # slicing sub_list = squares[1:3] # = [1,4] add = lambda x, y: x + y # lambda functions name = "Alice" # normal string greeting = f"Hello, {name}!" # formatted string (f-string)
Decorators
def my_decorator(func): def wrapper(): print("Decorator start.") func() print("Decorator end.") return wrapper @my_decorator def say_hello(): print("Decorated Function") say_hello()
Statements
# imports import math # import module from datetime import datetime # import specific function/class import module as alias # import module with alias from module import * # import all names from a module x = 5 # assignment x -= 1 # decrement # if else if x > 0: # conditional elif x < 0: # else if condition else: # else statement # loops for i in range(5): # for loop for _ in range(n): # for loop with unused n while x > 0: # while loop break # exit loop continue # skip to next iteration def my_function(): # function definition return 42 # return value pass # null operation (placeholder) class MyClass: # class definition # exceptions try: # Start of try block # ... except ZeroDivisionError: # Handle specific exception # ... finally: # runs no matter what # ... raise Exception("Err") # raise exception with open('file.txt', 'r') as file: # scoped resource management global x # declare global variable nonlocal y # declare non-local variable in nested function assert x == 4 # assert statement # async async def my_coroutine(): # define asynchronous function await some_async_function() # await asynchronous call async with some_async_context_manager: # async scoped resource manager # ... del x # Delete a variable or object # generators yield value # yield value from generator function yield from another_generator() # Yield all values from another generator if __name__ == "__main__": # check if script is run directly
Built-In Functions
# I/O print() # Output data to console input() # Reads a line of input from the user. help() # Invoke help system __debug__ # variable set to False if python is run with -O len() # Returns length (number of items) of object type() # Returns type of object. # casts int() # Convert value to integer float() # Convert value to float str() # Convert value to string bool() # Convert value to boolean list() # Create list from an iterable tuple() # Create tuple from an iterable set() # Create set from an iterable dict() # Create associative array # math max() # Return largest item (in iterable) min() # Return smallest item (in iterable) sum() # Return sum of numbers abs() # Return absolute value round() # Round number to specified decimal places # sorting sorted() # Returns a new sorted list from the elements of any iterable. reversed() # Returns a reversed iterator of a sequence. enumerate() # Adds a counter to an iterable and returns it as an enumerate object. zip() # Combines elements from multiple iterables into tuples. map() # Apply function to iterable and return map filter() # Construct iterator from elements of an iterable for which a function returns true. all() # Return True if all elements of an iterable are true any() # Returns True if any element of an iterable is true. If the iterable is empty, returns False.
# special attributes __doc__ # attribute that stores a docstring __loader__ # attribute for the module loader object ule loader object __name__ # attribute that stores name of module __package__ # attribute that stores package name of module __spec__ # attribute that stores module's import specification # internals __build_class__ # called internally by class statement __import__ # called internally by import statement
# async aiter(iterable) # return asynchronous iterator anext(iterator) # retrieve anext(iterator) # retrieve the next item from async iterator # binary bin(x) # convert integer to binary string hex(x) # convert integer to hexadecimal string oct(x) # convert integer to octal string breakpoint() # drop into the debugger at the call site # math complex(real, imag) # create complex number divmod(a, b) # return quotient and remainder of dividing by b pow(base, exp) # return base raised to the power of exp bytearray() # create mutable byte array bytes() # create immutable bytes object callable(obj) # check if object is callable # interpreter compile(src, file, mode) # compile source code into code object eval(expr) # evaluate python expression from string exec(object) # execute python code dynamically exit() # exit interpreter quit() # exit interpreter # program metadata copyright() # display copyright information credits() # display credits information license() # display license information # attributes getattr(obj, name) # retrieve attribute from object hasattr(obj, name) # check if object has specified attribute delattr(obj, name) # delete attribute from object setattr(obj, name, val) # set attribute on object property() # create property attribute dir(object) # return list of attributes and methods of object # data structures frozenset() # create immutable set format(value) # format value using specified format hash(object) # return hash value of object id(object) # return the identity of object # classes isinstance(object, classinfo) # check if object is instance of class issubclass(class, classinfo) # check if class is subclass of another staticmethod(func) # transform method into static method super() # return proxy object to access parent class methods classmethod(func) # transform method into class method globals() # return dict of current global symbol table locals() # return dict of current local symbol table next(iterator) # retrieve the next item from iterator memoryview(obj) # create memory view of object object() # create new featureless object open(file, mode) # open file and return file object # iterables iter(iterable) # return iterator for iterable range(start, stop) # generate sequence of numbers slice(start, stop, step) # create slice object zip(*iterables) # combine multiple iterables into tuples # plaintext ord(char) # return the unicode code point for given character repr(object) # return string representation of object ascii(object) # return printable representation of object chr(i) # return character string for unicode code point vars(object) # return the __dict__ attribute of object
Code Examples
Generators
A generator is a special type of iterator that allows iteration through a
sequence of values. Each time the yield
statement of a generator is executed,
the function's state is saved, and it can be resumed later.
def fibonacci(n): a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b fib_gen = fibonacci(4) # get generator object for number in fib_gen: # using the generator print(number)
Exceptions
try: numerator = 10 denominator = 0 result = numerator / denominator except ZeroDivisionError: print("Error: Cannot divide by zero.") else: print("Result:", result) finally: print("Execution completed.") # runs no matter what
Built-in Exceptions:
ArithmeticError AssertionError AttributeError BaseException BaseExceptionGroup BlockingIOError BrokenPipeError BufferError BytesWarning ChildProcessError ConnectionAbortedError ConnectionError ConnectionRefusedError ConnectionResetError DeprecationWarning EOFError Ellipsis EncodingWarning EnvironmentError Exception ExceptionGroup FileExistsError FileNotFoundError FloatingPointError FutureWarning GeneratorExit IOError ImportError ImportWarning IndentationError IndexError InterruptedError IsADirectoryError KeyError KeyboardInterrupt LookupError MemoryError ModuleNotFoundError NameError None NotADirectoryError NotImplemented NotImplementedError OSError OverflowError PendingDeprecationWarning PermissionError ProcessLookupError RecursionError ReferenceError ResourceWarning RuntimeError RuntimeWarning StopAsyncIteration StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError TimeoutError True TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UnicodeWarning UserWarning ValueError Warning ZeroDivisionError