0% found this document useful (0 votes)
37 views

Advanced Python Concepts

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views

Advanced Python Concepts

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Advanced Python Concepts

Here’s a comprehensive guide to advanced Python topics, including everything. You can use this as a
reference for your studies.

This guide covers a range of advanced Python concepts including decorators , context managers ,
callable objects , property decorators , abstract base classes , metaclasses , descriptors ,
data classes , function annotations , memoization , and the use of __slots__ .

1. Decorators

Function Decorators
Decorators modify the behavior of a function or method.

def my_decorator(func):
def wrapper():
print("Before function call.")
func()
print("After function call.")
return wrapper

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

say_hello()

Class Decorators
Class decorators modify classes.
def class_decorator(cls):
cls.extra_attribute = 'This is an extra attribute'
return cls

@class_decorator
class MyClass:
def greet(self):
return "Hello!"

obj = MyClass()
print(obj.extra_attribute) # Output: This is an extra attribute

2. Generators
Generators yield values one at a time, conserving memory.

def count_up_to(n):
count = 1
while count <= n:
yield count
count += 1

for number in count_up_to(5):


print(number)

3. Context Managers

Custom Context Managers


Use the with statement to manage resources.
class MyContext:
def __enter__(self):
print("Entering the context.")
return self

def __exit__(self, exc_type, exc_val, exc_tb):


print("Exiting the context.")

with MyContext() as ctx:


print("Inside the context.")

Context Managers with contextlib


Simplify context manager creation.

from contextlib import contextmanager

@contextmanager
def managed_resource():
print("Acquiring resource")
yield "Resource"
print("Releasing resource")

with managed_resource() as resource:


print(f"Using {resource}")

4. Callable Objects
Classes that implement __call__ can be invoked like functions.
class CallableClass:
def __init__(self, value):
self.value = value

def __call__(self, new_value):


self.value = new_value
return f'Value updated to {self.value}'

obj = CallableClass(10)
print(obj(20)) # Output: Value updated to 20

5. Property Decorators
Manage attribute access using properties.

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

@property
def value(self):
return self._value

@value.setter
def value(self, new_value):
if new_value < 0:
raise ValueError("Value cannot be negative.")
self._value = new_value

obj = MyClass(10)
print(obj.value) # Output: 10
obj.value = 15 # Updates value

6. Abstract Base Classes (ABCs)


Define abstract methods that must be implemented in derived classes.
from abc import ABC, abstractmethod

class Shape(ABC):
@abstractmethod
def area(self):
pass

class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
return 3.14 * (self.radius ** 2)

class Square(Shape):
def __init__(self, side):
self.side = side

def area(self):
return self.side ** 2

shapes = [Circle(5), Square(4)]


for shape in shapes:
print(f'Area: {shape.area()}')

7. Metaclasses
Metaclasses modify class creation.
Basic Example

class Meta(type):
def __new__(cls, name, bases, attrs):
attrs['greeting'] = 'Hello'
return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=Meta):
pass

obj = MyClass()
print(obj.greeting) # Output: Hello

Enforcing Naming Conventions

class NameEnforcer(type):
def __new__(cls, name, bases, attrs):
if not name.startswith("My"):
raise ValueError("Class name must start with 'My'.")
return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=NameEnforcer):
pass

# class AnotherClass(metaclass=NameEnforcer): # Raises error


# pass

obj = MyClass() # Works

8. Descriptors
Customize attribute access with descriptors.
class Descriptor:
def __get__(self, instance, owner):
return 'This is a descriptor value.'

def __set__(self, instance, value):


print(f'Setting value to {value}.')

class MyClass:
my_attr = Descriptor()

obj = MyClass()
print(obj.my_attr) # Output: This is a descriptor value.
obj.my_attr = 'New value' # Output: Setting value to New value.

9. Data Classes
Simplify class definitions for data storage.

from dataclasses import dataclass

@dataclass
class Point:
x: int
y: int

p1 = Point(1, 2)
print(p1) # Output: Point(x=1, y=2)

10. Function Annotations


Add metadata to function parameters and return values.

def add(a: int, b: int) -> int:


return a + b

print(add(2, 3)) # Output: 5


print(add.__annotations__) # Output: {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class
11. Using functools for Memoization
Cache function results for efficiency.

from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(10)) # Output: 55

12. __slots__ {#12--slots }


Optimize memory usage by limiting class attributes.

class MyClass:
__slots__ = ['attr1', 'attr2'] # Only these attributes can be used

def __init__(self, attr1, attr2):


self.attr1 = attr1
self.attr2 = attr2

obj = MyClass(1, 2)
print(obj.attr1) # Output: 1
# obj.attr3 = 3 # Raises an AttributeError

Author: Laksh Kumar Sisodiya


github: https://github.com/thefcraft

You might also like