- Trending Categories
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
Physics
Chemistry
Biology
Mathematics
English
Economics
Psychology
Social Studies
Fashion Studies
Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
What are generators and decorators in Python?
In this article, we will explain to you what are generators and decorators in python.
Generators have been an important part of python ever since they were introduced with PEP 255.
Generators in python are a special routine that can be used to control the iteration behavior of a loop. A generator is similar to a function returning an array. A generator has a parameter, which we can call and it generates a sequence of numbers. But unlike functions, which return a whole array, a generator yields one value at a time which requires less memory.
Any python function with the keyword “yield” may be called a generator. A normal python function starts execution from the first line and continues until we got a return statement or an exception or end of the function however, any of the local variables created during the function scope are destroyed and not accessible further. While in the case of the generator when it encounters a yield keyword the state of the function is frozen and all the variables are stored in memory until the generator is called again.
We can use a generator in accordance with an iterator or can be explicitly called using the “next” keyword.
Generally generators in Python −
Defined with the def keyword
Use the yield keyword
May contain several yield keywords.
Returns an iterator.
Generators are functions that return an iterable generator object. Because the values from the generator object are fetched one at a time rather than the entire list at once, you can use a for-loop, next(), or list() function to get the actual values.
Generator function
Generators can be created using the generator function and the generator expression.
A generator function is similar to a regular function, but instead of a return value, it has a yield keyword.
To create a generator function, add the yield keyword. The examples below demonstrate how to write a generator function.
Generators with Iterators
Example
# creating a function def generatorExample(): yield "T" yield "U" yield "T" yield "O" yield "R" yield "I" yield "A" yield "L" yield "S" # calling the generatorExample() function which is created above result = generatorExample() # Traversing in the above result(generator object) for k in result: # Printing the corresponding value print(k)
Output
T U T O R I A L S
Reading yield values from the generator
A list(), for-loop, and next() method can be used to read values from a generator object.
Reading values from a generator object using next()
The next() method returns the next item in a list, array, or object. When the list is empty and next() is called, it returns an error with the stopIteration signal. This error indicates that there are no more entries in the list.
Example
# creating a function that accepts a number as an argument def oddNumbers(num): # traversing till that number passed for i in range(num): # checking whether the iterator index value is an odd number if (i%2!=0): # getting the iterator index value if the condition is true using the yield keyword yield i # calling the above function to get the odd numbers below 8 result = oddNumbers(8) # calling the next items in the result list print(next(result)) print(next(result)) print(next(result)) print(next(result)) # throws an error since the list has no more elements print(next(result))
Output
1 3 5 7 Traceback (most recent call last): File "main.py", line 17, in <module> print(next(result)) StopIteration
Decorators in Python
Python offers an amazing tool called decorators to add functionality to an existing code.
This is also known as metaprogramming since a part of the program attempts to modify another portion of the program during the compile time.
Decorators use functions as arguments in another function, which is then invoked inside the wrapper function.
Syntax
@tutorials_decorator def python_decorator(): print("Hello tutorials Point") '''Above code is equivalent to - def python_decorator(): print("Hello tutorials Point") python_decorator = tutorials_decorator(python_decorator)'''
Here tutorials_decorator is a callable function that adds some code on top of another callable function, python_decorator and returns the wrapper function.
Example
Here func is the function that is being decorated and python_decorator is the function that is used to decorate it
# defining a decorator def python_decorator(func): def wrapper(): print("Text before calling the function") func() print("Text after calling the function") return wrapper def tutorials_decorator(): print("Hello tutorials Point!!!") tutorials_decorator = python_decorator(tutorials_decorator) tutorials_decorator()
Output
Text before calling the function Hello tutorials Point!!! Text after calling the function
python_decorator(func) − This is a decorator function; it takes another function as an argument and "decorates" it, which means it modifies it and returns the modified version.
wrapper − We define another inner function called wrapper within the decorator function. This is the actual function that modifies the passed function func by wrapping it.
The wrapper function is returned by the decorator.
tutorials_decorator − It is a normal function that we require to decorate. It only prints a simple statement here.
Syntactic Decorator
The decorator pattern described above became popular in the Python community, but it was a little complex. We must write the function name three times, and the decoration is hidden beneath the function definition.
As a result, Python added a new way to use decorators by including syntactic sugar with the @ symbol.
Syntax
@decorator def func(arg1, arg2, ...): pass
Syntactic sugar is a syntax used within a programming language to make things easier to read or express.
Example
The following example performs the same thing as the previous one −
# defining a decorator def python_decorator(func): def wrapper(): print("Text before calling the function") func() print("Text after calling the function") return wrapper @python_decorator def tutorials_decorator(): print("Hello tutorials Point!!!") tutorials_decorator()
Output
Text before calling the function Hello tutorials Point!!! Text after calling the function
It is the same as the previous example, the only difference is that we use @python_decorator instead of
tutorials_decorator = python_decorator(tutorials_decorator)
Conclusion
In this article, we learned about generators and decorators in Python in a nutshell. We also demonstrated how to use generators and decorators while writing code.