Skip to content

Advanced concepts in Python

Published: at 03:22 PM

Advanced Python Concepts

Table of contents

Open Table of contents

Decorators

Decorators are a powerful and flexible way to modify the behavior of functions or methods. They are often used for tasks such as logging, memoization, and access control.

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

Generators

Generators allow you to create iterators in a more concise way compared to using classes. They are useful for generating large sets of data on the fly.

def countdown(n):
    while n > 0:
        yield n
        n -= 1

for i in countdown(5):
    print(i)

Context Managers

Context managers are used for resource management (e.g., file handling, network connections) and are implemented using the with statement.

with open('example.txt', 'r') as file:
    content = file.read()
# File is automatically closed after the block

Metaclasses

Metaclasses are classes for classes. They allow you to customize class creation, often used for code generation and validation.

class MyMeta(type):
    def __new__(cls, name, bases, dct):
        # Custom logic here
        return super().__new__(cls, name, bases, dct)

class MyClass(metaclass=MyMeta):
    pass

Concurrency and Parallelism

Python provides modules like asyncio for asynchronous programming and multiprocessing for parallelism.

import asyncio

async def async_function():
    print("Async function")

asyncio.run(async_function())

Descriptors

Descriptors allow you to customize how attributes are accessed and modified.

class DescriptorExample:
    def __get__(self, instance, owner):
        return instance._value

    def __set__(self, instance, value):
        if value < 0:
            raise ValueError("Value must be positive")
        instance._value = value

class MyClass:
    descriptor = DescriptorExample()

    def __init__(self, value):
        self._value = value

obj = MyClass(42)
print(obj.descriptor)  # Calls __get__
obj.descriptor = -1    # Calls __set__

Type hints

Type hints allow you to add annotations to your code to indicate the expected types of variables and function return values. While not enforced at runtime, they can be used by tools like mypy for static type checking.

def add(x: int, y: int) -> int:
    return x + y