1. Advance Python
Advanced Python topics include various concepts that help in optimizing code, improving performance, and mastering more sophisticated features of the language. Here’s a brief overview of some key areas in advanced Python:
1. Generators and Iterators
- Generators: A simpler way to create iterators using the
yield
keyword. They are memory efficient and used for large data streams. - Example:
def count_up_to(max):count = 1while count <= max:yield countcount += 1counter = count_up_to(5)for number in counter:print(number)
- Iterators: Objects you can iterate over, implementing
__iter__()
and__next__()
methods.
2. Decorators
- Decorators: Functions that modify the behavior of another function or method. Useful for logging, validation, or performance measurement.
- Example:
def my_decorator(func):def wrapper():print("Something before the function.")func()print("Something after the function.")return wrapper@my_decoratordef say_hello():print("Hello!")say_hello()
3. Context Managers
- Context Managers: Use
with
statements to handle setup and teardown actions automatically (like opening/closing files). - Custom Context Managers: Can be created using the
__enter__
and__exit__
methods or by using thecontextlib
module. - Example:
class FileHandler:def __init__(self, filename, mode):self.filename = filenameself.mode = modedef __enter__(self):self.file = open(self.filename, self.mode)return self.filedef __exit__(self, exc_type, exc_val, exc_tb):self.file.close()with FileHandler('test.txt', 'w') as f:f.write('Hello, World!')
4. Metaprogramming
- Metaprogramming: Writing code that manipulates or generates other code. This includes techniques like modifying classes or functions at runtime using
type()
,getattr()
, andsetattr()
. - Example: Creating a class dynamically.
def create_class(name, bases, dct):return type(name, bases, dct)MyClass = create_class('MyClass', (object,), {'x': 5})obj = MyClass()print(obj.x)
5. Coroutines and asyncio
- Coroutines: A more advanced form of generators, used for asynchronous programming.
- Async/Await: Helps in writing non-blocking code, often used with network requests, databases, etc.
- Example:
import asyncioasync def fetch_data():print("Start fetching...")await asyncio.sleep(2)print("Data fetched")async def main():await fetch_data()asyncio.run(main())
6. Descriptors
- Descriptors: Provide a way to customize the behavior of attribute access by defining
__get__
,__set__
, and__delete__
methods. - Example:
class Descriptor:def __init__(self, value=None):self.value = valuedef __get__(self, instance, owner):print("Getting value")return self.valuedef __set__(self, instance, value):print("Setting value")self.value = valueclass MyClass:attr = Descriptor()obj = MyClass()obj.attr = 10print(obj.attr)
7. Multiprocessing and Multithreading
- Multiprocessing: Allows execution of multiple processes, each with its own memory space, using the
multiprocessing
module. - Multithreading: Concurrent execution in a single process.
threading
module can be used for I/O-bound tasks but has limitations due to Python’s Global Interpreter Lock (GIL). - Example (Multiprocessing):
from multiprocessing import Processdef print_number(num):print(f'Number: {num}')if __name__ == "__main__":p1 = Process(target=print_number, args=(1,))p1.start()p1.join()
8. Memory Management & Performance Optimization
- Memory management: Tools like
gc
(Garbage Collection) andsys
modules can help you manage memory more effectively. - Profiling: Use
cProfile
ortimeit
modules to analyze code performance. - Example (Profiling):
import cProfiledef example_function():total = sum(range(1000000))cProfile.run('example_function()')
9. Type Hints and Annotations
- Type hints improve code readability and allow better tooling support. Python does not enforce types, but tools like
mypy
can be used to enforce them. - Example:
def greet(name: str) -> str:return f"Hello, {name}"print(greet("Alice"))
10. Testing and Mocking
- Writing tests for your code using
unittest
,pytest
, and mocking dependencies usingunittest.mock
. - Example (unittest):
import unittestdef add(a, b):return a + bclass TestMath(unittest.TestCase):def test_add(self):self.assertEqual(add(1, 2), 3)if __name__ == "__main__":unittest.main()