Movatterモバイル変換


[0]ホーム

URL:


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

Commitc3b5057

Browse files
committed
Add section about function decorators.
1 parent9388654 commitc3b5057

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ written correctly.
9292
-[Lambda Expressions](src/functions/test_lambda_expressions.py) (`lambda` statement)
9393
-[Documentation Strings](src/functions/test_function_documentation_string.py)
9494
-[Function Annotations](src/functions/test_function_annotations.py)
95+
-[Function Decorators](src/functions/test_function_decorators.py)
9596
6.**Classes**
9697
-[Class Definition](src/classes/test_class_definition.py) (`class` statement)
9798
-[Class Objects](src/classes/test_class_objects.py)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""Function Decorators.
2+
3+
@see: https://www.thecodeship.com/patterns/guide-to-python-function-decorators/
4+
5+
Function decorators are simply wrappers to existing functions. In the context of design patterns,
6+
decorators dynamically alter the functionality of a function, method or class without having to
7+
directly use subclasses. This is ideal when you need to extend the functionality of functions that
8+
you don't want to modify. We can implement the decorator pattern anywhere, but Python facilitates
9+
the implementation by providing much more expressive features and syntax for that.
10+
"""
11+
12+
13+
deftest_function_decorators():
14+
"""Function Decorators."""
15+
16+
# Function decorators are simply wrappers to existing functions. Putting the ideas mentioned
17+
# above together, we can build a decorator. In this example let's consider a function that
18+
# wraps the string output of another function by p tags.
19+
20+
# This is the function that we цфте to decorate.
21+
defgreeting(name):
22+
return"Hello, {0}!".format(name)
23+
24+
# This function decorates another functions output with <p> tag.
25+
defdecorate_with_p(func):
26+
deffunction_wrapper(name):
27+
return"<p>{0}</p>".format(func(name))
28+
returnfunction_wrapper
29+
30+
# Now, let's call our decorator and pass the function we want decorate to it.
31+
my_get_text=decorate_with_p(greeting)
32+
33+
# Here we go, we've just decorated the function output without changing the function itself.
34+
assertmy_get_text('John')=='<p>Hello, John!</p>'# With decorator.
35+
assertgreeting('John')=='Hello, John!'# Without decorator.
36+
37+
# Now, Python makes creating and using decorators a bit cleaner and nicer for the programmer
38+
# through some syntactic sugar There is a neat shortcut for that, which is to mention the
39+
# name of the decorating function before the function to be decorated. The name of the
40+
# decorator should be prepended with an @ symbol.
41+
42+
@decorate_with_p
43+
defgreeting_with_p(name):
44+
return"Hello, {0}!".format(name)
45+
46+
assertgreeting_with_p('John')=='<p>Hello, John!</p>'
47+
48+
# Now let's consider we wanted to decorate our greeting function by one more functions to wrap a
49+
# div the string output.
50+
51+
# This will be our second decorator.
52+
defdecorate_with_div(func):
53+
deffunction_wrapper(text):
54+
return"<div>{0}</div>".format(func(text))
55+
returnfunction_wrapper
56+
57+
# With the basic approach, decorating get_text would be along the lines of
58+
# greeting_with_div_p = decorate_with_div(decorate_with_p(greeting_with_p))
59+
60+
# With Python's decorator syntax, same thing can be achieved with much more expressive power.
61+
@decorate_with_div
62+
@decorate_with_p
63+
defgreeting_with_div_p(name):
64+
return"Hello, {0}!".format(name)
65+
66+
assertgreeting_with_div_p('John')=='<div><p>Hello, John!</p></div>'
67+
68+
# One important thing to notice here is that the order of setting our decorators matters.
69+
# If the order was different in the example above, the output would have been different.
70+
71+
# Passing arguments to decorators.
72+
73+
# Looking back at the example before, you can notice how redundant the decorators in the
74+
# example are. 2 decorators(decorate_with_div, decorate_with_p) each with the same
75+
# functionality but wrapping the string with different tags. We can definitely do much better
76+
# than that. Why not have a more general implementation for one that takes the tag to wrap
77+
# with as a string? Yes please!
78+
79+
deftags(tag_name):
80+
deftags_decorator(func):
81+
deffunc_wrapper(name):
82+
return"<{0}>{1}</{0}>".format(tag_name,func(name))
83+
returnfunc_wrapper
84+
returntags_decorator
85+
86+
@tags('div')
87+
@tags('p')
88+
defgreeting_with_tags(name):
89+
return"Hello, {0}!".format(name)
90+
91+
assertgreeting_with_tags('John')=='<div><p>Hello, John!</p></div>'

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp