I have a Python function that I want to run from the context-menu. I am using the Windows Registry to call the function when a file is right clicked, and I want the function to receive the file selected.
The context menu item looks something like the Random Commands option.
The function I wish to run is foo1() in the file test1:
# in script test1.py
def foo1():
import sys
print(sys.argv)
I tried approaching the problem using the python -c switch to directly call the function:
python -c "import test1; test1.foo1()" %1
However, the value of sys.argv after selecting the file and executing is ['-c'], which doesn't include the file selected.
I also tried using an argument parser to dynamically import and run the function:
# in file registry_parser.py
import argparse
import os
import sys
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--func_name')
parser.add_argument('-f', '--file_name')
parser.add_argument('-p', '--file_path')
args = vars(parser.parse_args())
sys.path.insert(0, args['file_path'])
exec(f"import {args['file_name']}")
exec(f"{args['file_name']}.{args['func_name']}(sys.argv)")
And the function I would call from the registry is (paths simplified):
registry_parser.py --func_name foo1 --file_name test1 --file_path "[PATH TO registry_parser.py]" %1
However, I either get an error registry_parser.py: error: unrecognized arguments: %1 or the "%1" is parsed quite literally and ends up as a value in sys.argv.
Any help is appreciated.
So on all the forums I asked I never received a correct answer, but I found this Reddit Post that has an example to a solution. Hope this helps someone else.
I donĀ“t know, how to run a python file (python test.py) with extra stuff, like this:
python test.py "hello world"
python [FILE] [SAY]
What i want:
def something(say):
print(say)
A simple example of using argparse:
import argparse
cmd_parser = argparse.ArgumentParser()
cmd_parser.add_argument('SAY', help= 'The string you want to print on the
terminal')
args = cmd_parser.parse_args()
print(args.SAY)
I found a solution (a long time ago btw):
import sys
sys.argv
Thats it! It returns a list with all arguments:
C:\Programs >>> test.py-t "Hello, World!" start
["test.py","-t","Hello World","start"]
i want to import a .py file lets say param.py (which has some variable),through command line argument, also i want to redirect print statement of a main file let say test.py to a file.Also i want to use param.py variables to test.py script.Can anyone help me with this?here is my code.
For param.py
target_mac = "000000000000FFFF"
ACEM1_slave="20"
ACEM2_slave="11"
DCEM_slave="50"
For test.py
`//Please add the code, as per my requirement.`
I want to pass the argument in command line as: py test.py -f param.py -o out.txt
where, test.py is the main file,param.py is the config file. & out.txt is the log file.
Thank you.
How about something such as this, which uses argparse to parse the arguments, and runpy.run_path() to load the variables from the config file.
test.py
import argparse
import functools
import runpy
# Parse the script arguments
parser = argparse.ArgumentParser()
parser.add_argument('-f')
parser.add_argument('-o')
args = parser.parse_args()
# Load the config file
config = runpy.run_path(args.f)
# Open the output file for writing
output = open(args.o, 'a')
print >>output, 'This will go to the output file'
print >>output, config['target_mac']
print >>output, config['ACEM1_slave']
print >>output, config['ACEM2_slave']
print >>output, config['DCEM_slave']
# Flush and close the output file
output.flush()
output.close()
The variables would be available via the config dictionary and the print statements are redirected to the output file. It can be run as intended:
python test.py -f param.py -o out.txt
After running it, out.txt contains:
This will go to the output file
000000000000FFFF
20
11
50
You could even make the variables in param.py available as variables in the global scope for test.py.
# Load the config file
config = runpy.run_path(args.f)
# Update the global variables with the config
globals().update(config)
Then you could work with the variables directly in test.py:
print(target_mac)
How do you accept/parse command line arguments for a py file that has no class? Here is what I have inside my file test.py:
import sys
if __name__ == '__main__':
How do I get the arguments when the file is executed via command line? I call it via:
python test.py <arg1>
and obviously want the value of "arg1".
Look no further than sys.argv, which is a list containing all arguments passed to the program.
try:
arg = sys.argv[1]
except IndexError:
print "No argument specified."
sys.exit(1)
I have a Python script that needs to invoke another Python script in the same directory. I did this:
from subprocess import call
call('somescript.py')
I get the following error:
call('somescript.py')
File "/usr/lib/python2.6/subprocess.py", line 480, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
I have the script somescript.py in the same folder though. Am I missing something here?
If 'somescript.py' isn't something you could normally execute directly from the command line (I.e., $: somescript.py works), then you can't call it directly using call.
Remember that the way Popen works is that the first argument is the program that it executes, and the rest are the arguments passed to that program. In this case, the program is actually python, not your script. So the following will work as you expect:
subprocess.call(['python', 'somescript.py', somescript_arg1, somescript_val1,...]).
This correctly calls the Python interpreter and tells it to execute your script with the given arguments.
Note that this is different from the above suggestion:
subprocess.call(['python somescript.py'])
That will try to execute the program called python somscript.py, which clearly doesn't exist.
call('python somescript.py', shell=True)
Will also work, but using strings as input to call is not cross platform, is dangerous if you aren't the one building the string, and should generally be avoided if at all possible.
Windows? Unix?
Unix will need a shebang and exec attribute to work:
#!/usr/bin/env python
as the first line of script and:
chmod u+x script.py
at command-line or
call('python script.py'.split())
as mentioned previously.
Windows should work if you add the shell=True parameter to the "call" call.
Check out this.
from subprocess import call
with open('directory_of_logfile/logfile.txt', 'w') as f:
call(['python', 'directory_of_called_python_file/called_python_file.py'], stdout=f)
import subprocess
command = 'home/project/python_files/run_file.py {} {} {}'.format(
arg1, arg2, arg3) # if you want to pass any arguments
p = subprocess.Popen(
[command],
shell=True,
stdin=None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True)
out, err = p.communicate()
subprocess.call expects the same arguments as subprocess.Popen - that is a list of strings (the argv in C) rather than a single string.
It's quite possible that your child process attempted to run "s" with the parameters "o", "m", "e", ...
If you're on Linux/Unix you could avoid call() altogether and not execute an entirely new instance of the Python executable and its environment.
import os
cpid = os.fork()
if not cpid:
import somescript
os._exit(0)
os.waitpid(cpid, 0)
For what it's worth.
What's wrong with
import sys
from os.path import dirname, abspath
local_dir = abspath(dirname(__file__))
sys.path.append(local_dir)
import somescript
or better still wrap the functionality in a function, e.g. baz, then do this.
import sys
from os.path import dirname, abspath
local_dir = abspath(dirname(__file__))
sys.path.append(local_dir)
import somescript
somescript.baz()
There seem to be a lot of scripts starting python processes or forking, is that a requirement?
First, check if somescript.py is executable and starts with something along the lines of #!/usr/bin/python.
If this is done, then you can use subprocess.call('./somescript.py').
Or as another answer points out, you could do subprocess.call(['python', 'somescript.py']).
def main(argv):
host = argv[0]
type = argv[1]
val = argv[2]
ping = subprocess.Popen(['python ftp.py %s %s %s'%(host,type,val)],stdout = subprocess.PIPE,stderr = subprocess.PIPE,shell=True)
out = ping.communicate()[0]
output = str(out)
print output
The subprocess call is a very literal-minded system call. it can be used for any generic process...hence does not know what to do with a Python script automatically.
Try
call ('python somescript.py')
If that doesn't work, you might want to try an absolute path, and/or check permissions on your Python script...the typical fun stuff.