66it is pressed. To achieve this you implement a command object with the `execute`
77method for each menu item and pass to it.
88
9+ *About the example
10+ We have a menu containing two items. Each item accept a file name, one hides the file
11+ and the other deletes it. Both items have undo option.
12+ Each item is a MenuItem class that accept corresponding command as input and executes
13+ its `execute` method when it is pressed.
14+
915*TL;DR
1016Object oriented implementation of callback functions.
1117
1420https://docs.djangoproject.com/en/2.1/ref/request-response/#httprequest-objects
1521"""
1622
23+ import os
24+
1725
18- class Command :
26+ class HideFileCommand :
1927 """
20- The interface that commands implement. This is used to abstract invoker from
21- the command is going to handle the job.
28+ A command to hide a file given its name
2229 """
2330
24- def execute (self ):
25- raise NotImplementedError ()
31+ def __init__ (self ):
32+ # an array of files hidden, to undo them as needed
33+ self ._hidden_files = []
2634
35+ def execute (self , filename ):
36+ if os .path .isfile (filename ):
37+ print (f'hiding { filename } ' )
2738
28- class MakeBoldCommand (Command ):
29- """
30- A simple command to bold a text.
31- """
39+ os .rename (filename , f'.{ filename } ' )
40+ self ._hidden_files .append (filename )
41+ else :
42+ print (f'{ filename } dose not exists to hide' )
43+
44+ def undo (self ):
45+ if len (self ._hidden_files ) > 0 :
46+ filename = self ._hidden_files .pop ()
3247
33- def execute (self ):
34- print ('I am making it bold.' )
48+ print (f'un-hiding { filename } ' )
3549
50+ os .rename (f'.{ filename } ' , filename )
3651
37- class MakeItalicCommand (Command ):
52+
53+ class DeleteFileCommand :
3854 """
39- A simple command to italic a text.
55+ A command to delete a file given its name
4056 """
4157
42- def execute (self ):
43- print ('I am making it italic.' )
58+ def __init__ (self ):
59+ # an array of deleted files, to undo them as needed
60+ self ._deleted_files = []
61+
62+ # create a directory to store deleted files
63+ if not os .path .exists ('bin' ):
64+ os .makedirs ('bin' )
65+
66+ def execute (self , filename ):
67+ if os .path .isfile (filename ):
68+ print (f'deleting { filename } ' )
69+
70+ os .rename (filename , f'bin/{ filename } ' )
71+ self ._deleted_files .append (filename )
72+ else :
73+ print (f'{ filename } dose not exists to delete' )
74+
75+ def undo (self ):
76+ if len (self ._deleted_files ) > 0 :
77+ filename = self ._deleted_files .pop ()
78+
79+ print (f'un-deleting { filename } ' )
80+
81+ os .rename (f'bin/{ filename } ' , filename )
4482
4583
4684class MenuItem :
@@ -51,24 +89,42 @@ class MenuItem:
5189 def __init__ (self , command ):
5290 self ._command = command
5391
54- def on_press (self ):
55- self ._command .execute ()
92+ def on_do_press (self , filename ):
93+ self ._command .execute (filename )
94+
95+ def on_undo_press (self ):
96+ self ._command .undo ()
5697
5798
5899def main ():
59100 """
60- >>> item1 = MenuItem(MakeBoldCommand ())
101+ >>> item1 = MenuItem(DeleteFileCommand ())
61102
62- >>> item2 = MenuItem(MakeItalicCommand ())
103+ >>> item2 = MenuItem(HideFileCommand ())
63104
64- >>> item1.on_press()
65- I am making it bold.
105+ # create a file named `test-file` to work with
106+ >>> test_file_name = 'test-file'
107+ >>> open(test_file_name, 'w').close()
66108
67- >>> item2.on_press()
68- I am making it italic.
109+ # deleting `test-file`
110+ >>> item1.on_do_press(test_file_name)
111+ deleting test-file
112+
113+ # hiding `test-file` but it dose not exists
114+ >>> item2.on_do_press(test_file_name)
115+ test-file dose not exists to hide
116+
117+ # un-deleting `test-file`
118+ >>> item1.on_undo_press()
119+ un-deleting test-file
120+
121+ # hiding `test-file`
122+ >>> item2.on_do_press(test_file_name)
123+ hiding test-file
69124 """
70125
71126
72127if __name__ == "__main__" :
73128 import doctest
129+
74130 doctest .testmod ()
0 commit comments