cmd with three arguments

K

kaklis

Hi pythonistas,
While playing with the Python Standard Library, i came across "cmd".
So I'm trying to make a console application. Everything works fine, i
created many function with do_....(self, line) prefix, but when i
tried to create a function with more arguments
i can't make it work. e.g
def do_connect(self, ip, command):
Are there any work arounds

Thanks in advance

Antonis
 
T

Tim Chase

While playing with the Python Standard Library, i came across "cmd".
So I'm trying to make a console application. Everything works fine, i
created many function with do_....(self, line) prefix, but when i
tried to create a function with more arguments
i can't make it work. e.g
def do_connect(self, ip, command):

Are there any work arounds

You simply receive all the text after the command:

class C(Cmd):
def do_thing(self, arguments):
print repr(arguments)

If you want to split it, you can do it boringly:

def do_thing(self, arguments):
args = arguments.split()

or you can let Python's standard library do some heavy-lifting
for you:

import shlex
#...
def do_thing(self, arguments):
args = shlex.split(arguments)

-tkc
 
K

kaklis

You simply receive all the text after the command:

   class C(Cmd):
     def do_thing(self, arguments):
       print repr(arguments)

If you want to split it, you can do it boringly:

     def do_thing(self, arguments):
       args = arguments.split()

or you can let Python's standard library do some heavy-lifting
for you:

   import shlex
   #...
     def do_thing(self, arguments):
       args = shlex.split(arguments)

-tkc

Thanks, great answer!!!
 
P

Peter Otten

Hi pythonistas,
While playing with the Python Standard Library, i came across "cmd".
So I'm trying to make a console application. Everything works fine, i
created many function with do_....(self, line) prefix, but when i
tried to create a function with more arguments
i can't make it work. e.g
def do_connect(self, ip, command):

Are there any work arounds

Thanks in advance

Antonis

You have to split the user input into arguments yourself. You can do this in
the body of the do_xxx() methods, use a decorator, or subclass cmd.Cmd.

Here's a solution using a decorator:

import cmd
import inspect
import shlex

def split(f):
def g(self, line):
argvalues = shlex.split(line)
argnames = inspect.getargspec(f).args
argcount = len(argnames) - 1
if len(argvalues) != argcount:
print "Need exactly %d args" % argcount
return
return f(self, *argvalues)
return g

class Cmd(cmd.Cmd):
@split
def do_connect(self, ip, command):
print "ip=%r, command=%r" % (ip, command)


if __name__ == "__main__":
c = Cmd()
c.cmdloop()

And here's a subclass that avoids the need for explicit @split decorations:

import cmd
import inspect
import shlex

def split(f):
def g(line):
argvalues = shlex.split(line)
argnames = inspect.getargspec(f).args
argcount = len(argnames) -1
if len(argvalues) != argcount:
print "Need exactly %d args" % argcount
return
return f(*argvalues)
return g

class CmdBase(cmd.Cmd, object):
def __getattribute__(self, name):
attr = object.__getattribute__(self, name)
if name.startswith("do_"):
attr = split(attr)
return attr

class Cmd(CmdBase):
def do_connect(self, ip, command):
print "ip=%r, command=%r" % (ip, command)


if __name__ == "__main__":
c = Cmd()
c.cmdloop()

Now you've got an idea of the general direction you can certainly come up
with something less hackish ;)

Peter
 
K

kaklis

You have to split the user input into arguments yourself. You can do this in
the body of the do_xxx() methods, use a decorator, or subclass cmd.Cmd.

Here's a solution using a decorator:

import cmd
import inspect
import shlex

def split(f):
    def g(self, line):
        argvalues = shlex.split(line)
        argnames = inspect.getargspec(f).args
        argcount = len(argnames) - 1
        if len(argvalues) != argcount:
            print "Need exactly %d args" % argcount
            return
        return f(self, *argvalues)
    return g

class Cmd(cmd.Cmd):
    @split
    def do_connect(self, ip, command):
        print "ip=%r, command=%r" % (ip, command)

if __name__ == "__main__":
    c = Cmd()
    c.cmdloop()

And here's a subclass that avoids the need for explicit @split decorations:

import cmd
import inspect
import shlex

def split(f):
    def g(line):
        argvalues = shlex.split(line)
        argnames = inspect.getargspec(f).args
        argcount = len(argnames) -1
        if len(argvalues) != argcount:
            print "Need exactly %d args" % argcount
            return
        return f(*argvalues)
    return g

class CmdBase(cmd.Cmd, object):
    def __getattribute__(self, name):
        attr = object.__getattribute__(self, name)
        if name.startswith("do_"):
            attr = split(attr)
        return attr

class Cmd(CmdBase):
    def do_connect(self, ip, command):
        print "ip=%r, command=%r" % (ip, command)

if __name__ == "__main__":
    c = Cmd()
    c.cmdloop()

Now you've got an idea of the general direction you can certainly come up
with something less hackish ;)

Peter

Thanks great advice!
Antonis
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,771
Messages
2,569,587
Members
45,097
Latest member
RayE496148
Top