Intro
Python is a versatile and powerful language that plays a key role in automation, development, and data management. This refresher covers essential Python concepts, making it perfect for anyone looking to strengthen their foundation and boost productivity across various domains.
Comments
Types of Comments in Python
Single-Line Comments: Single-line comments begin with the # symbol. Everything after the # on the same line is ignored by Python.
1 2
# This is a single-line comment print("Hello, World!") # This is an inline comment
Multi-Line Comments: For multi line comments you can use multiple # symbols or triple quotes (’’’ or “”").
1 2 3 4 5 6 7 8
# This is a multi-line comment # Line 1 # Line 2 """ This is a multi-line comment explaining the purpose of the program. """
Docstrings: Docstrings (short for documentation strings) are a type of comment used to document modules, classes, methods, or functions. They are written using triple quotes (’’’ or “”").
1 2 3 4 5 6 7 8 9
def greet(name): """ This function greets a person by their name. Arguments: name: str - The name of the person to greet """ print(f"Hello, {name}!") print(greet.__doc__) # Access Docstring programmatically using the __doc__ attribute.
Data types
Python offers a diverse range of data types to efficiently handle various kinds of data. These data types are broadly categorized into primitive types and collection.
As a dynamically typed language, Python does not require explicit data type declarations when defining variables. Instead, the data type of a variable is automatically inferred based on the value assigned to it, enabling more flexible and concise code.
Primitive Data Types: Primitive data types represent single values and are the building blocks of Python.
- Numeric Types:
- Integer (int): Represents whole numbers
1 2
num = 42 print(type(num)) # Output: <class 'int'>
- Float (float): Represents decimal numbers
1 2
price = 19.99 print(type(price)) # Output: <class 'float'>
- Complex (complex): Represents complex numbers (real and imaginary parts).
1 2
z = 3 + 4j print(type(z)) # Output: <class 'complex'>
- Integer (int): Represents whole numbers
- Boolean (bool): Represents True or False values.
1 2
is_active = True print(type(is_active)) # Output: <class 'bool'>
- String (str): Represents text data.
1 2
name = "Alice" print(type(name)) # Output: <class 'str'>
- Numeric Types:
Collection Data Types: Collection types store multiple items in a single variable.
- List (list): A mutable, ordered collection of items. Allows duplicate values, supports indexing and slicing.
1 2 3 4 5 6 7 8 9
fruits = ["apple", "banana", "cherry"] print(type(fruits)) # Output: <class 'list'> print(fruits[0]) # Access the element at index 0, Output: apple print(fruits[0:1]) # Slicing, Access elements from index 0 to 1, Output: [apple, banana] fruits.append("guava") # Add new element fruits.insert("grapes") # Add new element fruits.remove() # Remove element fruits.pop() # Remove element fruits[1] = "custard-apple" # Modifying elements
- Tuple (tuple): An immutable, ordered collection of items (faster than lists.).
1 2
coordinates = (10, 20) print(type(coordinates)) # Output: <class 'tuple'>
- Set (set): An unordered collection of unique items. No duplicate values, supports mathematical operations like union and intersection.
1 2
unique_numbers = {1, 2, 3, 3} print(unique_numbers) # Output: {1, 2, 3}
- Dictionary (dict): A collection of key-value pairs. Keys must be unique, values can be of any type.
1 2 3 4 5
user = {"name": "Alice", "age": 25} print(type(user)) # Output: <class 'dict'> print(user[name]) # Output: Alice user["gender"] = "female" # set new key-value pair del user["age"] # remove key-value pair
- List (list): A mutable, ordered collection of items. Allows duplicate values, supports indexing and slicing.
Specialized Data Types: Python also supports specialized data types for specific use cases.
NoneType (None): Represents the absence of a value.
1 2
result = None print(type(result)) # Output: <class 'NoneType'>
Bytes (bytes): Represents immutable sequences of bytes (used for binary data).
1 2
data = b"hello" print(type(data)) # Output: <class 'bytes'>
Bytearray (bytearray): A mutable sequence of bytes.
1 2
data = bytearray(5) # Creates a bytearray of size 5 print(type(data)) # Output: <class 'bytearray'>
Type Conversion: Python allows you to convert data types using built-in functions.
Implicit Conversion: Python automatically converts types where safe.
1 2
result = 5 + 2.5 # int + float = float print(result, type(result)) # Output: 7.5 <class 'float'>
Explicit Conversion: Use functions like
int()
,float()
,str()
to convert types.1 2
num = "123" print(int(num)) # Output: 123
Operators
Operators are special symbols or keywords in Python that perform specific operations on variables and values.
Arithmetic Operators: Perform mathematical operations like addition, subtraction, multiplication, etc.
Operator Description Example Output + Addition 5 + 3 8 - Subtraction 5 - 3 2 * Multiplication 5 * 3 15 / Division 5 / 2 2.5 // Floor Division 5 // 2 2 % Modulus (remainder) 5 % 2 1 ** Exponentiation 2 ** 3 8 Comparison (Relational) Operators: Compares two values and return a boolean result (True or False).
Operator Description Example Output == Equal to 5 == 5 True != Not equal to 5 != 3 True > Greater than 5 > 3 True < Less than 5 < 3 False >= Greater than or equal to 5 >= 3 True <= Less than or equal to 5 <= 3 False Logical Operators: Combines conditional statements and return a boolean result.
Operator Description Example Output and Logical AND True and False False or Logical OR True or False True not Logical NOT not True False Assignment Operators: Assignment operators are used to assign values to variables, with optional arithmetic or bitwise operations.
Operator Description Example Equivalent To = Assign value x = 5 — += Add and assign x += 3 x = x + 3 -= Subtract and assign x -= 3 x = x - 3 *= Multiply and assign x *= 3 x = x * 3 /= Divide and assign x /= 3 x = x / 3 //= Floor divide and assign x //= 3 x = x // 3 %= Modulus and assign x %= 3 x = x % 3 **= Exponent and assign x **= 3 x = x ** 3 Bitwise Operators: Works on binary representations of numbers.
Operator Description Example Output & Bitwise AND 5 & 3 1 | Bitwise OR 5 | 3 7 ^ Bitwise XOR 5 ^ 3 6 ~ Bitwise NOT ~5 -6 « Left Shift 5 « 1 10 » Right Shift 5 » 1 2 Membership Operators: Checks if a value exists in a sequence.
Operator Description Example Output in Value exists in sequence “a” in “apple” True not in Value does not exist in sequence “b” not in “apple” True Identity Operators: Checks whether two variables refer to the same object in memory.
Operator Description Example Output is Same object a is b True is not Different objects a is not b False
Example:
|
|
Conditionals
Python uses the if
, elif
, and else
keywords to create conditional logic. The syntax is simple and readable:
Syntax:
|
|
Example:
|
|
Loops
Loops are an essential construct in Python that allow you to execute a block of code repeatedly. Python provides two main types of loops: for
and while
.
for
loop: The for loop in Python is used to iterate over a sequence (like a list, tuple, string, or range). It allows you to perform an action for every item in the sequence.
Syntax:
|
|
Example:
|
|
while
loop: The while loop continues to execute a block of code as long as its condition is True.
Syntax:
|
|
Example:
|
|
Functions
Functions are a fundamental building block in Python, allowing you to encapsulate reusable blocks of code. They enhance modularity, readability, and maintainability by enabling you to organize your code into meaningful units.
Example:
|
|
Function Parameters:
- Positional Arguments: Arguments passed in the order defined.
- Keyword Arguments: Arguments passed with parameter names for clarity.
- Default Parameters: Provide default values to parameters.
|
|
Variable-Length Arguments
- *args: Capture positional arguments as a tuple.
- **kwargs: Capture keyword arguments as a dictionary.
Example:
|
|
Modules & Packages
What is a Module?
A module is a single Python file containing reusable code. It can include variables, functions, classes, or other Python objects, and it helps in organizing and reusing code across projects.
Creating a Module: Simply create a .py file with Python code.
|
|
Using a Module: You can use the import statement to include a module in another script.
|
|
Aliasing Modules:
|
|
__name__
variable:
When Python scripts are executed, a special variable called __name__
is automatically set, Its value depends on whether the script is being run directly or imported as a module.
Direct Execution vs. Importing:
- If the script is executed directly,
__name__
is set to__main__
. - If the script is imported, name is set to the name of the module.
- If the script is executed directly,
Why Use if
__name__ == "__main__"
:?This construct allows you to include code in a module that executes only when the file is run directly, not when it is imported as part of another program:
|
|
- How It Works:
|
|
This ensures that the standalone script behavior and reusable module functionality are cleanly separated.
What is a Package?
A package is a collection of modules organized in directories. It contains an __init__.py
file, which marks the directory as a Python package. Packages allow hierarchical structuring of modules, making them scalable for large projects.
Creating a Package:
Create a directory structure:
1 2 3
my_package/ __init__.py math_operations.py
Add code to the modules: math_operations.py
1 2
def multiply(a, b): return a * b
Use the package in your project:
1 2 3
from my_package import math_operations print(math_operations.multiply(4, 5)) # Output: 20
Exception Handling
Exception handling allows developers to manage runtime errors gracefully, ensuring that a program does not crash unexpectedly and can provide meaningful feedback to users. Python achieves this through the try, except, else, and finally blocks.
What Are Exceptions?
An exception is an event that disrupts the normal flow of a program. Common examples of exceptions include:
- ZeroDivisionError: Division by zero.
- FileNotFoundError: File operations fail because the file does not exist.
- ValueError: Invalid value passed to a function.
- KeyError: Nonexistent key accessed in a dictionary.
Syntax:
|
|
Example 1: Handling a Specific Exception
|
|
Example 2: Catching Multiple Exceptions
You can handle different exceptions separately:
|
|
Example 3: Using else
The else block executes if no exception occurs:
|
|
Example 4: Using finally
The finally block executes regardless of whether an exception occurs:
|
|
Raising Exceptions:
You can raise exceptions explicitly using the raise keyword:
|
|
Custom Exceptions:
You can define your own exceptions by creating a custom class derived from Exception:
|
|
File Handling
File handling in Python allows you to read from and write to files, enabling persistent data storage. Python provides built-in functions and methods for file operations, making it straightforward to work with files.
File Handling Basics:
To work with files, the open() function is used. Its syntax is:
|
|
- file: The name or path of the file.
- mode: Specifies the purpose of opening the file (e.g., read, write, append).
File Modes:
Mode | Description |
---|---|
r | Read mode (default). File must exist. |
w | Write mode. Creates a file or truncates it. |
a | Append mode. Writes to the end of the file. |
x | Exclusive creation. Fails if the file exists. |
b | Binary mode (e.g., rb, wb). |
t | Text mode (default, e.g., rt, wt). |
Reading Files:
Python provides various methods to read file content:
Reading the Entire File:
1 2 3
with open('example.txt', 'r') as file: content = file.read() print(content)
Reading Line by Line:
1 2 3
with open('example.txt', 'r') as file: for line in file: print(line.strip())
Reading a Fixed Number of Characters:
1 2 3
with open('example.txt', 'r') as file: content = file.read(10) # Reads the first 10 characters print(content)
Writing to Files
You can write to a file using the write() method.
|
|
To append content:
|
|
File Handling with with
Using the with
statement ensures that the file is properly closed after operations, even if exceptions occur.
|
|
Checking if a File Exists
Use the os
module to check for file existence.
|
|
Example
Here’s a complete example of reading from one file and writing to another:
|
|
Regular expressions
Regular Expressions (regex) are powerful tools for pattern matching and text manipulation, frequently used in DevOps for tasks like log analysis, input validation, and parsing configuration files. Python provides the re module to work with regular expressions efficiently.
Syntax:
Literals: Characters that match themselves, such as a, 1, @.
Metacharacters: Special characters with a specific meaning:
- .: Matches any single character except a newline.
- ^: Anchors the match to the beginning of the string.
- $: Anchors the match to the end of the string.
- []: Character class to match any one of the characters inside.
- |: Alternation operator (OR), e.g., a|b matches either a or b.
- (): Groups patterns together for capturing.
Quantifiers: Control how many times a pattern should occur:
- *: 0 or more occurrences.
- +: 1 or more occurrences.
- ?: 0 or 1 occurrence.
- {n,m}: Between n and m occurrences.
Escape Sequences:
- \d: Matches any digit (0-9).
- \w: Matches any word character (letters, digits, underscore).
- \s: Matches any whitespace character (spaces, tabs, newlines).
To work with regular expressions in Python, you first need to import the re module.
|
|
Basic Functions in re Module
re.match(): Checks if the regular expression matches the beginning of the string.
1 2 3
pattern = r"^Hello" result = re.match(pattern, "Hello World") print(result.group()) # Output: Hello
re.search(): Searches for the pattern anywhere in the string.
1 2 3
pattern = r"World" result = re.search(pattern, "Hello World") print(result.group()) # Output: World
re.findall(): Returns all non-overlapping matches in a string as a list.
1 2 3
pattern = r"\d+" # Matches one or more digits result = re.findall(pattern, "There are 15 apples and 7 oranges.") print(result) # Output: ['15', '7']
re.sub(): Replaces occurrences of the pattern with a specified replacement.
1 2 3
pattern = r"apples" result = re.sub(pattern, "bananas", "There are 15 apples and 7 oranges.") print(result) # Output: There are 15 bananas and 7 oranges.
re.split(): Splits the string based on the given pattern.
1 2 3
pattern = r"\s+" # Split on one or more whitespace characters result = re.split(pattern, "This is a sample sentence.") print(result) # Output: ['This', 'is', 'a', 'sample', 'sentence.']
Lambdas
Lambda functions, also known as anonymous functions, are small, unnamed functions defined using the lambda keyword. They are commonly used when you need a simple function for a short period of time.
Syntax:
|
|
- The arguments represent the inputs to the function.
- The expression is a single statement that gets evaluated and returned.
Example:
|
|
Lambda functions are often used in combination with higher-order functions like map(), filter(), and reduce().
With map(): The map() function applies a function to all items in an iterable.
1 2 3
numbers = [1, 2, 3, 4] squared = map(lambda x: x ** 2, numbers) print(list(squared)) # Output: [1, 4, 9, 16]
With filter(): The filter() function filters elements in an iterable based on a condition.
1 2 3
numbers = [1, 2, 3, 4, 5, 6] even_numbers = filter(lambda x: x % 2 == 0, numbers) print(list(even_numbers)) # Output: [2, 4, 6]
With reduce(): The reduce() function, from the functools module, applies a rolling computation to a sequence.
1 2 3 4 5
from functools import reduce numbers = [1, 2, 3, 4] product = reduce(lambda x, y: x * y, numbers) print(product) # Output: 24
Closures
A closure is a function object that retains access to variables in its enclosing lexical scope, even after the scope has finished executing. Closures are a powerful tool for creating functions with behavior that depends on the context in which they were defined.
For a closure to occur, three conditions must be met:
- A nested function must exist inside an enclosing function.
- The nested function must reference a variable defined in the enclosing scope.
- The enclosing function must return the nested function.
Example:
|
|
Decorators
Decorators in Python are a powerful feature that allows you to modify the behavior of functions or methods. They are a key tool for writing concise, readable, and reusable code.
A decorator is essentially a function that takes another function as an argument and extends or alters its behavior. Decorators are often used for tasks such as logging, authentication, and performance monitoring.
Example:
|
|
Generators
Generators are a type of iterable, like lists or tuples, that yield items one at a time using the yield keyword. Unlike lists, they don’t store all values in memory, making them ideal for large data sets or infinite sequences.
A generator is a function that produces a sequence of values. When a generator function is called, it doesn’t execute immediately. Instead, it returns a generator object that can be iterated over.
Example:
|
|
Object oriented programming
Key concepts
- A class acts as a blueprint or template for creating objects. It defines the attributes (data) and methods (behaviors) that its objects will possess.
- Objects are instances of a class. Each object has its own set of attribute values, which can be unique.
- Attributes represent the characteristics or properties of an object. They are defined as variables within a class and can hold data specific to each instance.
- Methods are functions that belong to a class and define the actions or behaviors that objects can perform. They often operate on the object’s attributes.
Example:
|
|
Polymorphism
Polymorphism allows objects of different classes to be treated as instances of a common superclass. This means that the same method name can be used for different objects, with each object responding in its own specific way based on its class. It provides flexibility and enables writing more generic and reusable code.
Example:
|
|
Inheritance
Inheritance allows a class to reuse the properties and methods of parent class.
Example:
|
|
The super().__init__(name)
call in the Dog class’s constructor invokes the constructor of the parent class to initialize the name attribute.
Encapsulation
Encapsulation is a fundamental principle of object-oriented programming that restricts direct access to certain components of an object. This prevents unintended interference and ensures the object’s internal state is only modified through well-defined methods.
In Python, encapsulation is achieved using underscores to indicate private or protected attributes:
- Single Underscore (_): Used as a convention to indicate that an attribute or method is intended for internal use. It doesn’t prevent access but signals that it shouldn’t be accessed directly by external code.
- Double Underscore (__): Enforces name mangling, making the attribute or method more difficult to access directly. This is used to implement stricter encapsulation.
Example:
|
|
Abstraction
Abstraction focuses on hiding the implementation details of a class and exposing only the essential features. It simplifies the design of a system by reducing complexity and allowing developers to work with higher-level concepts without worrying about the underlying implementation. Python achieves abstraction through abstract base classes (ABCs)
Example:
|
|
That’s all for this refresher! Feel free to reach out with any questions or feedback. Happy coding! 🚀