0% found this document useful (0 votes)
17 views8 pages

Decor

Uploaded by

mshreyas817
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)
17 views8 pages

Decor

Uploaded by

mshreyas817
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

❖TABLE OF CONTENTS

1 Introduction

2 Python Decorators

2.1 Introduction to Decorators

2.2 Syntax and Basic Structure

2.3 Built-in decorators

3 Python Generators

3.1 Introduction to Generators

3.2 Generator Functions vs. Normal Functions

3.3 yield Keyword in Generators

3.4 Practical Use Cases of Generators

3.5 Generator Expressions

4 Comparison: Decorators vs. Generators

5 Conclusion
1. Introduction

Python is a powerful and flexible programming language with several advanced features that
allow developers to write clean, efficient, and reusable code. Two of the most important features
that make Python a favorite among developers are decorators and generators. Both are used to
simplify complex programming tasks and make code more readable and maintainable. This
report delves into the key concepts of decorators and generators, their usage, and how they
contribute to writing Pythonic code.

2. Python Decorators

2.1 Introduction to Decorators

A decorator in Python is a higher-order function that allows a user to modify the behavior of a
function or a class method without permanently altering it. Decorators enable you to "wrap" a
function, adding additional functionality before or after the main function’s execution. This
mechanism adheres to the DRY (Don't Repeat Yourself) principle, helping developers avoid code
duplication.

The concept of decorators is based on closures, where a function is defined within another
function and can capture variables from the enclosing scope. Decorators are widely used in
frameworks like Django and Flask to manage aspects such as authentication, logging, and
timing.

2.2 Syntax and Basic Structure

The syntax of decorators in Python is simple and uses the @decorator_name syntax. A decorator
is applied to a function by placing the decorator’s name above the function definition.

Example:
Python Copy code
def decorator_function(func):
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper

@decorator_function
def hello_world():
print("Hello, World!")

hello_world()

In this example, the decorator_function is applied to hello_world using the @decorator_function


syntax. When hello_world() is called, it is first passed through the decorator, and the additional
print statements are executed before and after the function’s original behavior.

2.3 Built-in Decorators


Python provides several built-in decorators that simplify common tasks, such as:

@staticmethod: Declares a static method that does not depend on instance variables.

@classmethod: Declares a class method that operates on the class itself rather than an
instance.

@property: Allows the method to be accessed like an attribute.

Example of @property:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius

@radius.setter
def radius(self, value):
if value <= 0:
raise ValueError("Radius must be positive")
self._radius = value

c = Circle(5)
print(c.radius) # Access as an attribute

3. Python Generators
3.1 Introduction to Generators

A generator in Python is a function that returns an iterator and generates a sequence of values
lazily, which means it yields one value at a time rather than storing the entire sequence in
memory. This makes generators memory-efficient and useful when dealing with large datasets or
infinite sequences.

Generators are created using the yield keyword, and they maintain their state between function
calls.

3.2 Generator Functions vs. Normal Functions

A generator function is defined just like a normal function but uses the yield keyword instead of
return. When a generator function is called, it does not execute immediately. Instead, it returns an
iterator object, which can be iterated over to retrieve values.
Example:

def simple_generator():

yield 1

yield 2

yield 3

gen = simple_generator()

print(next(gen)) # Outputs: 1

print(next(gen)) # Outputs: 2

print(next(gen)) # Outputs: 3

3.3 yield Keyword in Generators

The yield keyword suspends the function's execution and saves its state for resumption at a later
point. This allows generators to produce items one at a time, which is crucial for memory
efficiency.

Example:

def countdown(n):

while n > 0:

yield n

n -= 1

for number in countdown(5):

print(number)
3.4 Practical Use Cases of Generators

Reading Large Files Generators are useful when reading large files as they allow reading one line
at a time instead of loading the entire file into memory.

def read_large_file(file_path):

with open(file_path, 'r') as file:

for line in file:

yield line

for line in read_large_file('large_file.txt'):

print(line)

Fibonacci Sequence

def fibonacci_sequence():

a, b = 0, 1

while True:

yield a

a, b = b, a + b

fib_gen = fibonacci_sequence()

for _ in range(10):

print(next(fib_gen))
3.5 Generator Expressions

Generator expressions provide a concise way to create generators using a similar syntax to list
comprehensions, but they do not store the entire list in memory.

Example:

gen_exp = (x * x for x in range(10))

for num in gen_exp:

print(num)

4. Comparison: Decorators vs. Generators

Although both decorators and generators are advanced Python features, they serve distinct
purposes:

Decorators are used to modify the behavior of functions or methods, allowing the reuse of code
across multiple functions without altering their actual implementation.

Generators, on the other hand, are used to produce a sequence of values lazily, saving memory
when working with large datasets or infinite sequences.

In practice, decorators often make code more readable by abstracting repetitive tasks (like
logging or access control), while generators are essential for writing efficient, scalable programs
that work with large or infinite data streams.

5. Conclusion

Decorators and generators are essential components of Python that allow developers to write
more efficient, readable, and reusable code. Decorators provide a flexible way to modify or
extend the behavior of functions, while generators offer a memory-efficient way to work with
large data sets. Mastering these concepts leads to writing more Pythonic code and making full
use of Python's capabilities.

You might also like