argparse: how to parse a single string argument OR a file listing many arguments?
<p>I have a use case where I'd like the user to be able to provide, as an argument to argparse, EITHER a single string OR a filename where each line has a string.</p>

<p>Assume the user launches <code>./myscript.py -i foobar</code></p>

<p>The logical flow I'm looking for is something like this:</p>

<p>The script determines whether the string foobar is a readable file.
IF it is indeed a readable file, we call some function from the script, passing each line in <code>foobar</code> as an argument to that function.  If foobar is not a readable file, we call the same function but just use the string <code>foobar</code> as the argument and return. </p>

<p>I have no ability to guarantee that a filename argument will have a specific extension (or even an extension at all). </p>

<p>Is there a more pythonic way to do this OTHER than just coding up the logic exactly as I've described above?   I looked through the <a href="https://docs.python.org/2/howto/argparse.html" rel="nofollow">argparse tutorial</a> and didn't see anything, but it also seems reasonable to think that there would be some specific hooks for filenames as arguments, so I figured I'd ask.  </p>

<p>A way would be:</p>

<p>Let's say that you have created a parser like this:</p>

<pre><code>parser.add_argument('-i',  
                    help='...', 
                    type=function)
</code></pre>

<p>Where <code>type</code> points to the <code>function</code> which will be an outer function that evaluates the input of the user and decides if it is a <code>string</code> or a <code>filename</code></p>

<p>More information about <code>type</code> you can find in the <a href="https://docs.python.org/3/library/argparse.html#type" rel="nofollow">documentation</a>.</p>

<p>Here is a minimal example that demonstrates this use of <code>type</code>:</p>

<pre><code>parser.add_argument('-d','--directory', 
                    type=Val_dir, 
                    help='...')
# ....

def Val_dir(dir):
    if not os.path.isdir(dir):
        raise argparse.ArgumentTypeError('The directory you specified does not seem to exist!')
    else:
        return dir
</code></pre>

<p>The above example shows that with <code>type</code> we can control the input at parsing time. Of course in your case the function would implement another logic - evaluate if the input is a string or a filename.</p>

python argparse