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 a1ad8cd

Browse files
Mainly Updated Decorators Notebook
1 parent 6334f9f commit a1ad8cd

File tree

4 files changed

+396
-31
lines changed

4 files changed

+396
-31
lines changed

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.ipynb_checkpoints/

‎Decorators.ipynb

Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "8b964602",
6+
"metadata": {},
7+
"source": [
8+
"# Decorator\n",
9+
"\n",
10+
"- A design pattern that allows you to modify the functionality of a function by wrapping it in another function.\n",
11+
"- The outer function is called the decorator, which takes the original function as an argument and returns a modified version of it.\n",
12+
"\n",
13+
"\n",
14+
"## 1. Prerequisites\n",
15+
"\n",
16+
"Intuition of the following concepts:\n",
17+
"\n",
18+
"- Nested Function\n",
19+
"- Pass Function as Argument\n",
20+
"- Return a Function as a Value\n"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 1,
26+
"id": "0b983a66",
27+
"metadata": {},
28+
"outputs": [
29+
{
30+
"name": "stdout",
31+
"output_type": "stream",
32+
"text": [
33+
"11\n"
34+
]
35+
}
36+
],
37+
"source": [
38+
"# Nested Function : include one function inside another\n",
39+
"\n",
40+
"def outer(x):\n",
41+
" def inner(y):\n",
42+
" return x + y\n",
43+
" return inner\n",
44+
"\n",
45+
"\n",
46+
"add_five = outer(5)\n",
47+
"result = add_five(6)\n",
48+
"print(result)"
49+
]
50+
},
51+
{
52+
"cell_type": "code",
53+
"execution_count": 2,
54+
"id": "251844da",
55+
"metadata": {},
56+
"outputs": [
57+
{
58+
"name": "stdout",
59+
"output_type": "stream",
60+
"text": [
61+
"10\n"
62+
]
63+
}
64+
],
65+
"source": [
66+
"# Pass Function as Argument: pass a function as an argument to another function\n",
67+
"\n",
68+
"def add(x, y):\n",
69+
" return x + y\n",
70+
"\n",
71+
"def calculate(func, x, y):\n",
72+
" return func(x, y)\n",
73+
"\n",
74+
"result = calculate(add, 4, 6)\n",
75+
"print(result)"
76+
]
77+
},
78+
{
79+
"cell_type": "code",
80+
"execution_count": 3,
81+
"id": "b3715ab8",
82+
"metadata": {},
83+
"outputs": [
84+
{
85+
"name": "stdout",
86+
"output_type": "stream",
87+
"text": [
88+
"Hello, Ali!\n"
89+
]
90+
}
91+
],
92+
"source": [
93+
"# Return a Function as a Value: return a function as a return value\n",
94+
"\n",
95+
"def greeting(name):\n",
96+
" def hello():\n",
97+
" return \"Hello, \" + name + \"!\"\n",
98+
" return hello\n",
99+
"\n",
100+
"greet = greeting(\"Ali\")\n",
101+
"print(greet())"
102+
]
103+
},
104+
{
105+
"cell_type": "markdown",
106+
"id": "4c0c92c9",
107+
"metadata": {},
108+
"source": [
109+
"## 2. Decorator\n",
110+
"\n",
111+
"**A Python decorator is a function that takes in a function and returns it by adding some functionality.**\n",
112+
"\n",
113+
"- A decorator takes in a function, adds some functionality and returns it."
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"execution_count": 4,
119+
"id": "d2ac0c36",
120+
"metadata": {},
121+
"outputs": [
122+
{
123+
"name": "stdout",
124+
"output_type": "stream",
125+
"text": [
126+
"I got decorated.\n",
127+
"I am ordinary function.\n"
128+
]
129+
}
130+
],
131+
"source": [
132+
"def wrapper_func(func): # decorator func\n",
133+
" def inner_func():\n",
134+
" print(\"I got decorated.\")\n",
135+
" func()\n",
136+
" return inner_func\n",
137+
"\n",
138+
"def ordinary_func():\n",
139+
" print(\"I am ordinary function.\")\n",
140+
"\n",
141+
"\n",
142+
"# decorate the ordinary function\n",
143+
"decorated_func = wrapper_func(ordinary_func)\n",
144+
"# call the decorated function\n",
145+
"decorated_func()\n",
146+
" "
147+
]
148+
},
149+
{
150+
"cell_type": "markdown",
151+
"id": "27f541d7",
152+
"metadata": {},
153+
"source": [
154+
"## 3. @ Symbol With Decorator\n",
155+
"\n",
156+
"- Instead of assigning the function call to a variable, a much more elegant way to achieve this functionality using the @ symbol. "
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"execution_count": 5,
162+
"id": "0ec237f5",
163+
"metadata": {},
164+
"outputs": [
165+
{
166+
"name": "stdout",
167+
"output_type": "stream",
168+
"text": [
169+
"I got decorated.\n",
170+
"I am ordinary function.\n"
171+
]
172+
}
173+
],
174+
"source": [
175+
"def wrapper_func(func): # decorator func\n",
176+
" def inner_func():\n",
177+
" print(\"I got decorated.\")\n",
178+
" func()\n",
179+
" return inner_func\n",
180+
"\n",
181+
"\n",
182+
"@wrapper_func\n",
183+
"def ordinary_func():\n",
184+
" print(\"I am ordinary function.\")\n",
185+
"\n",
186+
"\n",
187+
"# call the decorated function\n",
188+
"ordinary_func()\n",
189+
" "
190+
]
191+
},
192+
{
193+
"cell_type": "markdown",
194+
"id": "4129ca4e",
195+
"metadata": {},
196+
"source": [
197+
"## 4. Decorating Functions with Parameters"
198+
]
199+
},
200+
{
201+
"cell_type": "code",
202+
"execution_count": 6,
203+
"id": "49543b4f",
204+
"metadata": {},
205+
"outputs": [
206+
{
207+
"name": "stdout",
208+
"output_type": "stream",
209+
"text": [
210+
"I am going to divide 2 and 5\n",
211+
"0.4\n",
212+
"I am going to divide 2 and 0\n",
213+
"Whoops! cannot divide\n"
214+
]
215+
}
216+
],
217+
"source": [
218+
"def smart_divide(func):\n",
219+
" def inner(a, b):\n",
220+
" print(\"I am going to divide\", a, \"and\", b)\n",
221+
" if b == 0:\n",
222+
" print(\"Whoops! cannot divide\")\n",
223+
" return\n",
224+
" func(a, b)\n",
225+
" # return func(a, b)\n",
226+
" return inner\n",
227+
"\n",
228+
"@smart_divide\n",
229+
"def divide(a, b):\n",
230+
" print(a/b)\n",
231+
"\n",
232+
"divide(2,5)\n",
233+
"\n",
234+
"divide(2,0)"
235+
]
236+
},
237+
{
238+
"cell_type": "markdown",
239+
"id": "754c8413",
240+
"metadata": {},
241+
"source": [
242+
"## 4. Chaining Decorators in Python\n",
243+
"\n",
244+
"- Multiple decorators can be chained in Python.\n",
245+
"- Apply multiple decorators to a single function by placing them one after the other, \n",
246+
" - with the most inner decorator being applied first."
247+
]
248+
},
249+
{
250+
"cell_type": "code",
251+
"execution_count": 7,
252+
"id": "ea096020",
253+
"metadata": {},
254+
"outputs": [
255+
{
256+
"name": "stdout",
257+
"output_type": "stream",
258+
"text": [
259+
"***************\n",
260+
"%%%%%%%%%%%%%%%\n",
261+
"Hello\n",
262+
"%%%%%%%%%%%%%%%\n",
263+
"***************\n"
264+
]
265+
}
266+
],
267+
"source": [
268+
"def star(func):\n",
269+
" def inner(*args, **kwargs):\n",
270+
" print(\"*\" * 15)\n",
271+
" func(*args, **kwargs)\n",
272+
" print(\"*\" * 15)\n",
273+
" return inner\n",
274+
"\n",
275+
"\n",
276+
"def percent(func):\n",
277+
" def inner(*args, **kwargs):\n",
278+
" print(\"%\" * 15)\n",
279+
" func(*args, **kwargs)\n",
280+
" print(\"%\" * 15)\n",
281+
" return inner\n",
282+
"\n",
283+
"\n",
284+
"@star\n",
285+
"@percent\n",
286+
"def printer(msg):\n",
287+
" print(msg)\n",
288+
"\n",
289+
"printer(\"Hello\")"
290+
]
291+
},
292+
{
293+
"cell_type": "code",
294+
"execution_count": 8,
295+
"id": "165d545a",
296+
"metadata": {},
297+
"outputs": [
298+
{
299+
"name": "stdout",
300+
"output_type": "stream",
301+
"text": [
302+
"calc_square took 18.98813247680664 mil sec\n",
303+
"calc_cube took 31.980276107788086 mil sec\n"
304+
]
305+
}
306+
],
307+
"source": [
308+
"# Example Scenario\n",
309+
"\n",
310+
"import time\n",
311+
"def time_it(func): # Wrapper Function\n",
312+
" def wrapper(*args, **kwargs):\n",
313+
" start = time.time()\n",
314+
" result = func(*args,**kwargs)\n",
315+
" end = time.time()\n",
316+
" print(func.__name__ +\" took \" + str((end-start)*1000) + \" mil sec\")\n",
317+
" return result\n",
318+
" return wrapper\n",
319+
"\n",
320+
"@time_it\n",
321+
"def calc_square(numbers):\n",
322+
" result = []\n",
323+
" for number in numbers:\n",
324+
" result.append(number*number)\n",
325+
" return result\n",
326+
"\n",
327+
"@time_it\n",
328+
"def calc_cube(numbers):\n",
329+
" result = []\n",
330+
" for number in numbers:\n",
331+
" result.append(number*number*number)\n",
332+
" return result\n",
333+
"\n",
334+
"array = range(1,100000)\n",
335+
"out_square = calc_square(array)\n",
336+
"out_cube = calc_cube(array)"
337+
]
338+
},
339+
{
340+
"cell_type": "markdown",
341+
"id": "77b00b78",
342+
"metadata": {},
343+
"source": [
344+
"*A `Decorator` takes in a function, adds some functionality and returns it*"
345+
]
346+
}
347+
],
348+
"metadata": {
349+
"kernelspec": {
350+
"display_name": "Python 3 (ipykernel)",
351+
"language": "python",
352+
"name": "python3"
353+
},
354+
"language_info": {
355+
"codemirror_mode": {
356+
"name": "ipython",
357+
"version": 3
358+
},
359+
"file_extension": ".py",
360+
"mimetype": "text/x-python",
361+
"name": "python",
362+
"nbconvert_exporter": "python",
363+
"pygments_lexer": "ipython3",
364+
"version": "3.9.7"
365+
}
366+
},
367+
"nbformat": 4,
368+
"nbformat_minor": 5
369+
}

0 commit comments

Comments
(0)

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