Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b8ef046

Browse files
Decorators
1 parent 095d496 commit b8ef046

File tree

9 files changed

+288
-0
lines changed

9 files changed

+288
-0
lines changed

‎08.Decorators/decorators-1.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#decorators-1.py
2+
# Decorators, as simple as it gets :)
3+
4+
# Decorators are functions that compliment other functions,
5+
# or in other words, modify a function or method.
6+
7+
# In the example below, we have a function named `decorated`.
8+
# This function just prints "This happened".
9+
# We have a decorator created named `inner_decorator()`.
10+
# This decorator function has an function within, which
11+
# does some operations (print stuff for simplicity) and then
12+
# returns the return-value of the internal function.
13+
14+
# How does it work?
15+
# a) The function `decorated()` gets called.
16+
# b) Since the decorator `@my_decorator` is defined above
17+
# `decorated()`, `my_decorator()` gets called.
18+
# c) my_decorator() takes a function name as args, and hence `decorated()`
19+
# gets passed as the arg.
20+
# d) `my_decorator()` does it's job, and when it reaches `myfunction()`
21+
# calls the actual function, ie.. decorated()
22+
# e) Once the function `decorated()` is done, it gets back to `my_decorator()`.
23+
# f) Hence, using a decorator can drastically change the behavior of the
24+
# function you're actually executing.
25+
26+
27+
def my_decorator(my_function): # <-- (4)
28+
def inner_decorator(): # <-- (5)
29+
print("This happened before!") # <-- (6)
30+
my_function() # <-- (7)
31+
print("This happens after ") # <-- (10)
32+
print("This happened at the end!") # <-- (11)
33+
34+
return inner_decorator
35+
# return None
36+
37+
38+
@my_decorator # <-- (3)
39+
def decorated(): # <-- (2) <-- (8)
40+
print("This happened!") # <-- (9)
41+
42+
43+
if __name__ == "__main__":
44+
decorated() # <-- (1)
45+
46+
47+
'''
48+
O/P-
49+
This happened before!
50+
This happened!
51+
This happens after
52+
This happened at the end!
53+
'''

‎08.Decorators/decorators-2.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# decorators-2.py
2+
# An updated version of decorators-1.py
3+
4+
# This code snippet takes the previous example, and add a bit more information
5+
# to the output.
6+
7+
import datetime
8+
9+
10+
def my_decorator(inner):
11+
def inner_decorator():
12+
print(datetime.datetime.utcnow())
13+
inner()
14+
print(datetime.datetime.utcnow())
15+
16+
return inner_decorator
17+
18+
19+
@my_decorator
20+
def decorated():
21+
print("This happened!")
22+
23+
24+
if __name__ == "__main__":
25+
decorated()
26+
27+
'''
28+
O/P: (NOTE: The time will change of course :P)
29+
30+
2022年07月16日 12:24:18.704572
31+
This happened!
32+
2022年07月16日 12:24:18.704572
33+
'''

‎08.Decorators/decorators-3.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# This is an updated version of decorators-2.py.
2+
# Here, the `decorated()` function takes an argument
3+
# and prints it back on terminal.
4+
5+
# When the decorator `@my_decorator` is called, it
6+
# takes the function `decorated()` as its argument, and
7+
# the argument of `decorated()` as the argument of `inner_decorator()`.
8+
# Hence the arg `number` is passed to `num_copy`.
9+
10+
import datetime
11+
12+
13+
def my_decorator(inner):
14+
def inner_decorator(num_copy):
15+
print(datetime.datetime.utcnow())
16+
inner(int(num_copy) + 1)
17+
print(datetime.datetime.utcnow())
18+
19+
return inner_decorator
20+
21+
22+
@my_decorator
23+
def decorated(number):
24+
print("This happened : " + str(number))
25+
26+
27+
if __name__ == "__main__":
28+
decorated(5)
29+
30+
'''
31+
O/P-
32+
2022年07月16日 12:26:14.060603
33+
This happened : 6
34+
2022年07月16日 12:26:14.060603
35+
'''

‎08.Decorators/decorators-4.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#decorators-4.py
2+
3+
# This example builds on the previous decorator examples.
4+
# The previous example, decorators-3.py showed how to
5+
# deal with one argument passed to the function.
6+
7+
# This example shows how we can deal with multiple args.
8+
9+
# Reminder : `args` is a list of arguments passed, while
10+
# kwargs is a dictionary passed as arguments.
11+
12+
13+
def decorator(inner):
14+
def inner_decorator(*args, **kwargs):
15+
print(args, kwargs)
16+
17+
return inner_decorator
18+
19+
20+
@decorator
21+
def decorated(string_args):
22+
print("This happened : " + string_args)
23+
24+
25+
if __name__ == "__main__":
26+
decorated("Hello, how are you?")
27+
28+
# This prints :
29+
# # python 22-decorators-4.py
30+
# ('Hello, how are you?',)

‎08.Decorators/decorators-5.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#decorators-5.py
2+
3+
4+
from __future__ import print_function
5+
6+
7+
# 2. Decorator function
8+
def handle_exceptions(func_name):
9+
def inner(*args, **kwargs):
10+
try:
11+
return func_name(*args, **kwargs)
12+
except Exception:
13+
print("An exception was thrown : ", Exception)
14+
15+
return inner
16+
17+
18+
# 1. Main function
19+
@handle_exceptions
20+
def divide(x, y):
21+
return x / y
22+
23+
24+
print(divide(8, 0))
25+
26+
'''
27+
O/P-
28+
An exception was thrown : <class 'Exception'>
29+
None
30+
'''

‎08.Decorators/decorators-6.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
def decorator(inner):
3+
def inner_decorator(*args, **kwargs):
4+
print("This function takes " + str(len(args)) + " arguments")
5+
inner(*args)
6+
7+
return inner_decorator
8+
9+
10+
@decorator
11+
def decorated(string_args):
12+
print("This happened: " + str(string_args))
13+
14+
15+
@decorator
16+
def alsoDecorated(num1, num2):
17+
print("Sum of " + str(num1) + "and" + str(num2) + ": " + str(num1 + num2))
18+
19+
20+
if __name__ == "__main__":
21+
decorated("Hello")
22+
alsoDecorated(1, 2)
23+
24+
'''
25+
O/P-
26+
This function takes 1 arguments
27+
This happened: Hello
28+
This function takes 2 arguments
29+
Sum of 1and2: 3
30+
'''

‎08.Decorators/decorators-7.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#decorators-7.py
2+
3+
# We have two functions, one which adds two numbers,
4+
# and another which subtracts two numbers.
5+
6+
# We apply the decorator @double which takes in the
7+
# functions that is called with the decorator, and doubles
8+
# the output of the respective function.
9+
10+
11+
def double(my_func):
12+
def inner_func(a, b):
13+
return 2 * my_func(a, b)
14+
15+
return inner_func
16+
17+
18+
@double
19+
def adder(a, b):
20+
return a + b
21+
22+
23+
@double
24+
def subtractor(a, b):
25+
return a - b
26+
27+
28+
print(adder(5, 6)) #22
29+
print(subtractor(8, 2)) #12

‎08.Decorators/decorators-class.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#class-decorators.py
2+
3+
# Till the previous examples, we saw function decorators.
4+
# But decorators can be applied to Classes as well.
5+
# This example deals with class decorators.
6+
7+
# NOTE: If you are creating a decorator for a class, you'll it
8+
# to return a Class.
9+
10+
# NOTE: Similarly, if you are creating a decorator for a function,
11+
# you'll need it to return a function.
12+
13+
14+
def honirific(cls):
15+
class HonirificCls(cls):
16+
def full_name(self):
17+
return "Ms." + super(HonirificCls, self).full_name()
18+
19+
return HonirificCls
20+
21+
22+
@honirific
23+
class Name(object):
24+
def __init__(self, first_name, last_name):
25+
self.first_name = first_name
26+
self.last_name = last_name
27+
28+
def full_name(self):
29+
return " ".join([self.first_name, self.last_name])
30+
31+
32+
result = Name("Shikha", "Pandey").full_name()
33+
print("Full name: {0}".format(result))
34+
35+
#Full name: Ms.Shikha Pandey
36+
# This needs further check. Erroring out.

‎README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
05. [Inheritance](https://github.com/Shikha-code36/Object-Oriented-Programming-OOPs-Python#05-inheritance)
99
06. [Encapsulation](https://github.com/Shikha-code36/Object-Oriented-Programming-OOPs-Python#06-encapsulation)
1010
07. [Polymorphism](https://github.com/Shikha-code36/Object-Oriented-Programming-OOPs-Python#07-polymorphism)
11+
08. [Decorators](https://github.com/Shikha-code36/Object-Oriented-Programming-OOPs-Python#08-decorators)
1112

1213
------------
1314
## What do you understand by OOPs?
@@ -149,4 +150,15 @@ Polymorphism in python defines methods in the child class that have the same nam
149150

150151
[Detailed Explanation](07.Polymorphism)
151152

153+
------------
154+
------------
155+
#### 08. Decorators
156+
157+
A decorator takes in a function, adds some functionality and returns it.
158+
Decorators are used to add functionality to an existing code.
159+
160+
This is also called metaprogramming because a part of the program tries to modify another part of the program at compile time.
161+
162+
[Detailed Explanation](08.Decorators)
163+
152164
------------

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /