FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
python-patterns/patterns/behavioral/command.py at master · CheoR/python-patterns · GitHub
CheoR
/
python-patterns
Public
forked from
faif/python-patterns
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
python-patterns
/
patterns
/
behavioral
/
command.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
107 lines (77 loc) · 2.83 KB
Breadcrumbs
python-patterns
/
patterns
/
behavioral
/
command.py
Copy path
File metadata and controls
107 lines (77 loc) · 2.83 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Command pattern decouples the object invoking a job from the one who knows
how to do it. As mentioned in the GoF book, a good example is in menu items.
You have a menu that has lots of items. Each item is responsible for doing a
special thing and you want your menu item just call the execute method when
it is pressed. To achieve this you implement a command object with the execute
method for each menu item and pass to it.
*About the example
We have a menu containing two items. Each item accepts a file name, one hides the file
and the other deletes it. Both items have an undo option.
Each item is a MenuItem class that accepts the corresponding command as input and executes
it's execute method when it is pressed.
*TL;DR
Object oriented implementation of callback functions.
*Examples in Python ecosystem:
Django HttpRequest (without execute method):
https://docs.djangoproject.com/en/2.1/ref/request-response/#httprequest-objects
"""
from
typing
import
List
,
Union
class
HideFileCommand
:
"""
A command to hide a file given its name
"""
def
__init__
(
self
)
->
None
:
# an array of files hidden, to undo them as needed
self
.
_hidden_files
:
List
[
str
]
=
[]
def
execute
(
self
,
filename
:
str
)
->
None
:
print
(
f"hiding
{
filename
}
"
)
self
.
_hidden_files
.
append
(
filename
)
def
undo
(
self
)
->
None
:
filename
=
self
.
_hidden_files
.
pop
()
print
(
f"un-hiding
{
filename
}
"
)
class
DeleteFileCommand
:
"""
A command to delete a file given its name
"""
def
__init__
(
self
)
->
None
:
# an array of deleted files, to undo them as needed
self
.
_deleted_files
:
List
[
str
]
=
[]
def
execute
(
self
,
filename
:
str
)
->
None
:
print
(
f"deleting
{
filename
}
"
)
self
.
_deleted_files
.
append
(
filename
)
def
undo
(
self
)
->
None
:
filename
=
self
.
_deleted_files
.
pop
()
print
(
f"restoring
{
filename
}
"
)
class
MenuItem
:
"""
The invoker class. Here it is items in a menu.
"""
def
__init__
(
self
,
command
:
Union
[
HideFileCommand
,
DeleteFileCommand
])
->
None
:
self
.
_command
=
command
def
on_do_press
(
self
,
filename
:
str
)
->
None
:
self
.
_command
.
execute
(
filename
)
def
on_undo_press
(
self
)
->
None
:
self
.
_command
.
undo
()
def
main
():
"""
>>> item1 = MenuItem(DeleteFileCommand())
>>> item2 = MenuItem(HideFileCommand())
# create a file named `test-file` to work with
>>> test_file_name = 'test-file'
# deleting `test-file`
>>> item1.on_do_press(test_file_name)
deleting test-file
# restoring `test-file`
>>> item1.on_undo_press()
restoring test-file
# hiding `test-file`
>>> item2.on_do_press(test_file_name)
hiding test-file
# un-hiding `test-file`
>>> item2.on_undo_press()
un-hiding test-file
"""
if
__name__
==
"__main__"
:
import
doctest
doctest
.
testmod
()
Back
|
FazBrowse Home
|
New Git URL