As a system administrator I find myself many times writing scripts that call command via subprocess. Sometimes, I don’t want the commands to actually execute, and I want just to see what would be executed. Hence, my codes were full in lines like this:
alaroffcmd = 'someBinary -h %s' %someHostName
...
if options.tstmd:
print alaroffcmd
else:
chctxt = sp.Popen(alamoffcmd,shell=True, stdout=sp.PIPE)
...
I was thinking that a ‘testmode’ would be very usefull.
As an example of usage:
lsp=nPopen('ls -l',shell=True, stdout=sp.PIPE, testmode=True)
Will just print the command to be issued. This seems redundant maybe, but in real life, I sometimes call subprocess with some very complex command, which are decided based on conditions that are determined in the script (above there is an example with someHostName)
I used this as an example how to extend a function by overriding it’s init method,. Here is how I extended subprocess.Popen, to fit my needs:
import subprocess as sp
class nPopen(sp.Popen):
def __init__(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,testmode=False):
if testmode:
print args
return None
p = sp.Popen.__init__(self,args, bufsize, executable,
stdin, stdout, stderr,
preexec_fn, close_fds, shell,
cwd, env, universal_newlines,
startupinfo, creationflags)
return p
This works as I expect it, but since I have never extended a class by overriding its __init__ method, I was wondering about the correctness of this, or in other words:
Is there a more Pythonic way to do this?
Should I use super for better Python3 compatibility ?
I wouldn’t use a subclass at all, since it sounds like you don’t want to change the functionality of the
Popenobject. It sounds like you just want to change the functionality of its constructor.I would create a dummy
Popenclass that just prints out its arguments. (This is written using Python 3.x style, but it’s easy enough to translate to Python 2.x.)You can then trigger use of the dummy class however you want.
Or even:
This takes advantage of the “duck typing” conventions of Python — any object which has the same interface as a
Popenobject is functionally indistinguishable from aPopenobject, as long as you don’t abuseisinstance()too much.Note that both of these methods allow you to import
Popenfrom the module.