This module allows one to create a command to call a Python function from the command line, and to call that function with arguments from the command line without using getopt or optparse
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 | """
PythonCall.py
PythonCall is a shortcut that allows a CLI command with arguments to call
any function within a Python module with only two lines of plumbing code.
Usage
=====
* Add code below to bottom of Python module.
if __name__ == "__main__":
import sys, PythonCall
PythonCall.PythonCall(sys.argv).execute()
* From command line or desktop shortcut, build a command of form:
<pythonpath> <module> <function> <arg1 arg2 ...>
Example: C:\Python25\python.exe C:\Dev\PyUtils\src\TextUtils.py xclip wrap 64
Notes
=====
* Called functions must expect args to be strings and do their own conversions.
* No argument checking or error-checking.
* In case of exception, PythonCall sends message to stderr.
* I often use this with text I pass in via the clipboard, which requires
code to read and write the clipboard (not included here).
Tested with Windows; should work on other platforms.
Jack Trainor 2008
"""
import os, os.path
import sys
import types
class PythonCall(object):
def __init__(self, sysArgs):
try:
self.function = None
self.args = []
self.modulePath = sysArgs[0]
self.moduleDir, tail = os.path.split(self.modulePath)
self.moduleName, ext = os.path.splitext(tail)
__import__(self.moduleName)
self.module = sys.modules[self.moduleName]
if len(sysArgs) > 1:
self.functionName = sysArgs[1]
self.function = self.module.__dict__[self.functionName]
self.args = sysArgs[2:]
except Exception, e:
sys.stderr.write("%s %s\n" % ("PythonCall#__init__", e))
def execute(self):
try:
if self.function:
self.function(*self.args)
except Exception, e:
sys.stderr.write("%s %s\n" % ("PythonCall#execute", e))
#####################################################
# Test Examples - REMOVE
#
# Normally the function calls are in a module other than PythonCall.
# These are only examples.
#
# Example 1: C:\Python25\python.exe C:\Dev\PyUtils\src\PythonCall.py double 14
# Example 2: C:\Python25\python.exe C:\Dev\PyUtils\src\PythonCall.py capitalize "Four score and seven years ago..."
#####################################################
def double(x):
x = int(x)
print 2 * x
def capitalize(s):
print s.upper()
if __name__ == "__main__":
import sys, PythonCall
PythonCall.PythonCall(sys.argv).execute()
#####################################################
# End - REMOVE
#####################################################
|
I wanted a quick, flexible way to create commands or Windows shortcuts that would call my Python functions without having to add getopt or optparse parsing sections to the bottom of my Python source.
I mostly use this code with to process text in and out of the clipboard (such as wrap to a number of columns) by double-clicking on a desktop shortcut.
(This is a big improvement to an earlier version of this recipe which included an extra function and was harder to follow.)
Fixed a bug, added some testing. Coerced args in getCommand to strings. Added the testing section at bottom of module to show how Passer and PythonCall work.