- Python Basics
- Python - Home
- Python - Overview
- Python - History
- Python - Features
- Python vs C++
- Python - Hello World Program
- Python - Application Areas
- Python - Interpreter
- Python - Environment Setup
- Python - Virtual Environment
- Python - Basic Syntax
- Python - Variables
- Python - Data Types
- Python - Type Casting
- Python - Unicode System
- Python - Literals
- Python - Operators
- Python - Arithmetic Operators
- Python - Comparison Operators
- Python - Assignment Operators
- Python - Logical Operators
- Python - Bitwise Operators
- Python - Membership Operators
- Python - Identity Operators
- Python - Operator Precedence
- Python - Comments
- Python - User Input
- Python - Numbers
- Python - Booleans
- Python Control Statements
- Python - Control Flow
- Python - Decision Making
- Python - If Statement
- Python - If else
- Python - Nested If
- Python - Match-Case Statement
- Python - Loops
- Python - for Loops
- Python - for-else Loops
- Python - While Loops
- Python - break Statement
- Python - continue Statement
- Python - pass Statement
- Python - Nested Loops
- Python Functions & Modules
- Python - Functions
- Python - Default Arguments
- Python - Keyword Arguments
- Python - Keyword-Only Arguments
- Python - Positional Arguments
- Python - Positional-Only Arguments
- Python - Arbitrary Arguments
- Python - Variables Scope
- Python - Function Annotations
- Python - Modules
- Python - Built in Functions
- Python Strings
- Python - Strings
- Python - Slicing Strings
- Python - Modify Strings
- Python - String Concatenation
- Python - String Formatting
- Python - Escape Characters
- Python - String Methods
- Python - String Exercises
- Python Lists
- Python - Lists
- Python - Access List Items
- Python - Change List Items
- Python - Add List Items
- Python - Remove List Items
- Python - Loop Lists
- Python - List Comprehension
- Python - Sort Lists
- Python - Copy Lists
- Python - Join Lists
- Python - List Methods
- Python - List Exercises
- Python Tuples
- Python - Tuples
- Python - Access Tuple Items
- Python - Update Tuples
- Python - Unpack Tuples
- Python - Loop Tuples
- Python - Join Tuples
- Python - Tuple Methods
- Python - Tuple Exercises
- Python Sets
- Python - Sets
- Python - Access Set Items
- Python - Add Set Items
- Python - Remove Set Items
- Python - Loop Sets
- Python - Join Sets
- Python - Copy Sets
- Python - Set Operators
- Python - Set Methods
- Python - Set Exercises
- Python Dictionaries
- Python - Dictionaries
- Python - Access Dictionary Items
- Python - Change Dictionary Items
- Python - Add Dictionary Items
- Python - Remove Dictionary Items
- Python - Dictionary View Objects
- Python - Loop Dictionaries
- Python - Copy Dictionaries
- Python - Nested Dictionaries
- Python - Dictionary Methods
- Python - Dictionary Exercises
- Python Arrays
- Python - Arrays
- Python - Access Array Items
- Python - Add Array Items
- Python - Remove Array Items
- Python - Loop Arrays
- Python - Copy Arrays
- Python - Reverse Arrays
- Python - Sort Arrays
- Python - Join Arrays
- Python - Array Methods
- Python - Array Exercises
- Python File Handling
- Python - File Handling
- Python - Write to File
- Python - Read Files
- Python - Renaming and Deleting Files
- Python - Directories
- Python - File Methods
- Python - OS File/Directory Methods
- Python - OS Path Methods
- Object Oriented Programming
- Python - OOPs Concepts
- Python - Classes & Objects
- Python - Class Attributes
- Python - Class Methods
- Python - Static Methods
- Python - Constructors
- Python - Access Modifiers
- Python - Inheritance
- Python - Polymorphism
- Python - Method Overriding
- Python - Method Overloading
- Python - Dynamic Binding
- Python - Dynamic Typing
- Python - Abstraction
- Python - Encapsulation
- Python - Interfaces
- Python - Packages
- Python - Inner Classes
- Python - Anonymous Class and Objects
- Python - Singleton Class
- Python - Wrapper Classes
- Python - Enums
- Python - Reflection
- Python Errors & Exceptions
- Python - Syntax Errors
- Python - Exceptions
- Python - try-except Block
- Python - try-finally Block
- Python - Raising Exceptions
- Python - Exception Chaining
- Python - Nested try Block
- Python - User-defined Exception
- Python - Logging
- Python - Assertions
- Python - Built-in Exceptions
- Python Multithreading
- Python - Multithreading
- Python - Thread Life Cycle
- Python - Creating a Thread
- Python - Starting a Thread
- Python - Joining Threads
- Python - Naming Thread
- Python - Thread Scheduling
- Python - Thread Pools
- Python - Main Thread
- Python - Thread Priority
- Python - Daemon Threads
- Python - Synchronizing Threads
- Python Synchronization
- Python - Inter-thread Communication
- Python - Thread Deadlock
- Python - Interrupting a Thread
- Python Networking
- Python - Networking
- Python - Socket Programming
- Python - URL Processing
- Python - Generics
- Python Libraries
- NumPy Tutorial
- Pandas Tutorial
- SciPy Tutorial
- Matplotlib Tutorial
- Django Tutorial
- OpenCV Tutorial
- Python Miscellenous
- Python - Date & Time
- Python - Maths
- Python - Iterators
- Python - Generators
- Python - Closures
- Python - Decorators
- Python - Recursion
- Python - Reg Expressions
- Python - PIP
- Python - Database Access
- Python - Weak References
- Python - Serialization
- Python - Templating
- Python - Output Formatting
- Python - Performance Measurement
- Python - Data Compression
- Python - CGI Programming
- Python - XML Processing
- Python - GUI Programming
- Python - Command-Line Arguments
- Python - Docstrings
- Python - JSON
- Python - Sending Email
- Python - Further Extensions
- Python - Tools/Utilities
- Python - GUIs
- Python Useful Resources
- Python Compiler
- NumPy Compiler
- Matplotlib Compiler
- SciPy Compiler
- Python - Questions & Answers
- Python - Online Quiz
- Python - Programming Examples
- Python - Quick Guide
- Python - Useful Resources
- Python - Discussion
Python - Decorators
A Decorator in Python is a function that receives another function as argument. The argument function is the one to be decorated by decorator. The behaviour of argument function is extended by the decorator without actually modifying it.
In this chapter, we whall learn how to use Python decorator.
Function in Python is a first order object. It means that it can be passed as argument to another function just as other data types such as number, string or list etc. It is also possible to define a function inside another function. Such a function is called nested function. Moreover, a function can return other function as well.
Syntax
The typical definition of a decorator function is as under −
def decorator(arg_function): #arg_function to be decorated def nested_function(): #this wraps the arg_function and extends its behaviour #call arg_function arg_function() return nested_function
Here a normal Python function −
def function(): print ("hello")
You can now decorate this function to extend its behaviour by passing it to decorator −
function=decorator(function)
If this function is now executed, it will show output extended by decorator.
Example 1
Following code is a simple example of decorator −
def my_function(x): print("The number is=",x) def my_decorator(some_function,num): def wrapper(num): print("Inside wrapper to check odd/even") if num%2 == 0: ret= "Even" else: ret= "Odd!" some_function(num) return ret print ("wrapper function is called") return wrapper no=10 my_function = my_decorator(my_function, no) print ("It is ",my_function(no))
The my_function() just prints out the received number. However, its behaviour is modified by passing it to a my_decorator. The inner function receives the number and returns whether it is odd/even. Output of above code is −
wrapper function is called Inside wrapper to check odd/even The number is= 10 It is Even
Example 2
An elegant way to decorate a function is to mention just before its definition, the name of decorator prepended by @ symbol. The above example is re-written using this notation −
def my_decorator(some_function): def wrapper(num): print("Inside wrapper to check odd/even") if num%2 == 0: ret= "Even" else: ret= "Odd!" some_function(num) return ret print ("wrapper function is called") return wrapper @my_decorator def my_function(x): print("The number is=",x) no=10 print ("It is ",my_function(no))
Python's standard library defines following built-in decorators −
@classmethod Decorator
The classmethod is a built-in function. It transforms a method into a class method. A class method is different from an instance method. Instance method defined in a class is called by its object. The method received an implicit object referred to by self. A class method on the other hand implicitly receives the class itself as first argument.
Syntax
In order to declare a class method, the following notation of decorator is used −
class Myclass: @classmethod def mymethod(cls): #....
The @classmethod form is that of function decorator as described earlier. The mymethod receives reference to the class. It can be called by the class as well as its object. That means Myclass.mymethod as well as Myclass().mymethod both are valid calls.
Example 3
Let us understand the behaviour of class method with the help of following example −
class counter: count=0 def __init__(self): print ("init called by ", self) counter.count=counter.count+1 print ("count=",counter.count) @classmethod def showcount(cls): print ("called by ",cls) print ("count=",cls.count) c1=counter() c2=counter() print ("class method called by object") c1.showcount() print ("class method called by class") counter.showcount()
In the class definition count is a class attribute. The __init__() method is the constructor and is obviously an instance method as it received self as object reference. Every object declared calls this method and increments count by 1.
The @classmethod decorator transforms showcount() method into a class method which receives reference to the class as argument even if it is called by its object. It can be seen even when c1 object calls showcount, it displays reference of counter class.
It will display the following output −
init called by <__main__.counter object at 0x000001D32DB4F0F0> count= 1 init called by <__main__.counter object at 0x000001D32DAC8710> count= 2 class method called by object called by <class '__main__.counter'> count= 2 class method called by class called by <class '__main__.counter'>
@staticmethod Decorator
The staticmethod is also a built-in function in Python standard library. It transforms a method into a static method. Static method doesn't receive any reference argument whether it is called by instance of class or class itself. Following notation used to declare a static method in a class −
Syntax
class Myclass: @staticmethod def mymethod(): #....
Even though Myclass.mymethod as well as Myclass().mymethod both are valid calls, the static method receives reference of neither.
Example 4
The counter class is modified as under −
class counter: count=0 def __init__(self): print ("init called by ", self) counter.count=counter.count+1 print ("count=",counter.count) @staticmethod def showcount(): print ("count=",counter.count) c1=counter() c2=counter() print ("class method called by object") c1.showcount() print ("class method called by class") counter.showcount()
As before, the class attribute count is increment on declaration of each object inside the __init__() method. However, since mymethod(), being a static method doesn't receive either self or cls parameter. Hence value of class attribute count is displayed with explicit reference to counter.
The output of the above code is as below −
init called by <__main__.counter object at 0x000002512EDCF0B8> count= 1 init called by <__main__.counter object at 0x000002512ED48668> count= 2 class method called by object count= 2 class method called by class count= 2
@property Decorator
Python's property() built-in function is an interface for accessing instance variables of a class. The @property decorator turns an instance method into a "getter" for a read-only attribute with the same name, and it sets the docstring for the property to "Get the current value of the instance variable."
You can use the following three decorators to define a property −
@property − Declares the method as a property.
@<property-name>.setter: − Specifies the setter method for a property that sets the value to a property.
@<property-name>.deleter − Specifies the delete method as a property that deletes a property.
A property object returned by property() function has getter, setter, and delete methods.
property(fget=None, fset=None, fdel=None, doc=None)
The fget argument is the getter method, fset is setter method. It optionally can have fdel as method to delete the object and doc is the documentation string.
The property() object's setter and getter may also be assigned with the following syntax also.
speed = property() speed=speed.getter(speed, get_speed) speed=speed.setter(speed, set_speed)
Where get_speed() and set_speeds() are the instance methods that retrieve and set the value to an instance variable speed in Car class.
The above statements can be implemented by @property decorator. Using the decorator car class is re-written as −
class car: def __init__(self, speed=40): self._speed=speed return @property def speed(self): return self._speed @speed.setter def speed(self, speed): if speed<0 or speed>100: print ("speed limit 0 to 100") return self._speed=speed return c1=car() print (c1.speed) #calls getter c1.speed=60 #calls setter
Property decorator is very convenient and recommended method of handling instance attributes.