Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General Command pattern and Command Dispatch pattern in Python

I was looking for a Command pattern implementation in Python... (According to Wikipedia,

the command pattern is a design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time.

)

The only thing I found was Command Dispatch pattern:

class Dispatcher:

    def do_get(self): ...

    def do_put(self): ...

    def error(self): ...

    def dispatch(self, command):
        mname = 'do_' + command
        if hasattr(self, mname):
            method = getattr(self, mname)
            method()
        else:
            self.error()

May be I'm wrong, but it looks like these are two different concepts, which accidentally have similar names.

Am i missing something?

like image 739
legesh Avatar asked Sep 07 '25 16:09

legesh


1 Answers

The simplest command pattern is already built into Python, simply use a callable:

def greet(who):
    print "Hello %s" % who

greet_command = lambda: greet("World")
# pass the callable around, and invoke it later
greet_command()

The command pattern as an object oriented design pattern makes more sense if your commands need to be able to do more than just be invoked. Common usecase is when you need to be able to undo/redo your actions. Then a command class is a good way to couple the forward and backwards actions together. For example:

class MoveFileCommand(object):
    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
        os.rename(self.src, self.dest)
    def undo(self):
        os.rename(self.dest, self.src)

undo_stack = []
undo_stack.append(MoveFileCommand('foo.txt', 'bar.txt'))
undo_stack.append(MoveFileCommand('bar.txt', 'baz.txt'))
# foo.txt is now renamed to baz.txt
undo_stack.pop().undo() # Now it's bar.txt
undo_stack.pop().undo() # and back to foo.txt
like image 195
Ants Aasma Avatar answered Sep 10 '25 02:09

Ants Aasma