I have a lot of arguments to pass to my main.py
. It's easier to store them in a txt file. So, i would like to know best way of using "config" files to pass CL args.
Shell script is not what i need, unfortunatly.
Asked
Active
Viewed 8,042 times
4

Ladenkov Vladislav
- 1,247
- 2
- 21
- 45
-
... Other than a shell script? – Ignacio Vazquez-Abrams Feb 06 '18 at 19:35
-
How is your current `main.py` parsing its args? – Robᵩ Feb 06 '18 at 19:43
-
@Robᵩ I don't know yet. I'am able to implement it as i need it – Ladenkov Vladislav Feb 06 '18 at 19:47
-
1Related: https://stackoverflow.com/questions/27433316/how-to-get-argparse-to-read-arguments-from-a-file-with-an-option-rather-than-pre – Robᵩ Feb 06 '18 at 20:02
-
1Even more related: https://docs.python.org/2/library/argparse.html#fromfile-prefix-chars – Robᵩ Feb 06 '18 at 20:04
3 Answers
5
If you plan to use argparse
, then fromfile_prefix_chars
is designed to solve exactly this problem.
In your launching program, put all of the arguments, one per line, into a file. Pass @file.txt
to your child program. In your child program, pass a fromfile_prefix_chars
parameter to the ArgumentParser()
constructor:
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
argparse
takes care of the rest for you.
Here is an example:
from argparse import ArgumentParser
parser = ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('-f', '--foo')
parser.add_argument('--bar')
parser.add_argument('q', nargs='*')
ns = parser.parse_args()
print(ns)
The contents of foo.txt
:
-f
1
--bar=2
q one
q two
The command line and the output:
$ python zz.py @foo.txt
Namespace(bar='2', foo='1', q=['q one', 'q two'])

Robᵩ
- 163,533
- 20
- 239
- 308
-
actually, i have been expecting diffuculties when putting more than one arg in the file. Can you please give an example of a file and argument parsing with 2 arguments – Ladenkov Vladislav Feb 06 '18 at 21:45
-
3
Use configparser. It uses .ini files and it's really easy to use.
Config file:
[DEFAULT]
KeepAlive = 45
ForwardX11 = yes
Example Code:
>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
>>> for key in config['bitbucket.org']: print(key)
...
keepalive
forwardx11
>>> default = config['default']
>>> default['keepalive']
'45'
>>> default['ForwardX11']
'yes'

Josh Abraham
- 959
- 1
- 8
- 18
-
That's very good. But i expected something more simple and beautiful, anyway – Ladenkov Vladislav Feb 06 '18 at 19:42
-
2You should add a direct answer in here, as the content of link could be changed. – timiTao Feb 06 '18 at 19:46
1
Here is a simple function that converts any @foo
argument into the contents of foo
, one argument per line. After the conversion, you may use sys.argv
in any of the normal ways.
import sys
def expand_arg_files(args):
for arg in args:
if arg.startswith('@'):
with open(arg[1:]) as f:
file_args = f.read().splitlines()
yield from expand_arg_files(file_args)
else:
yield arg
sys.argv[:] = expand_arg_files(sys.argv[:])
print(sys.argv)
Notes:
- The generator delegation syntax requires Python3.3 or higher.
- You may have
@
args inside the argument file. The expansion is recursive.

Robᵩ
- 163,533
- 20
- 239
- 308