Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
25 views

Advanced Python Concepts

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Advanced Python Concepts

Copyright
© © All Rights Reserved
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