2016-09-06 105 views
0

我想将文件的名称解析为字符串,而不是直接将文件转换为对象。Arg解析:将文件名解析为字符串(python)

这里是一个示例代码,test.py

import argparse 
import os.path 
def is_valid_file(parser, arg): 
     if not os.path.exists(arg): 
      parser.error("The file %s does not exist! Use the --help flag for input options." % arg) 
     else: 
      return open(arg, 'r') 

parser = argparse.ArgumentParser(description='test') 
parser.add_argument("-test", dest="testfile", required=True, 
        help="test", type=lambda x: is_valid_file(parser, x)) 
args = parser.parse_args()  
print args.testfile 

testfile.txt文件包含:1,2,3,4

在主要想print args.testfile作为字符串返回的testfile调用的名称:

$ python test.py -test test.txt 
>> "test.txt" 

为了达到这个我需要防止argparser从将test.txt转换为对象。我怎样才能做到这一点?

非常感谢!

+1

你有没有尝试过'解析器。add_argument(“ - test”,dest =“testfile”,required = True, help =“test”)' –

+0

感谢Jean-François,我写了一个前面的函数来检查文件的存在,解决了这个问题。 –

+0

上述功能: #_____ 高清is_valid_file(解析器,ARG): 如果没有os.path.exists(ARG): parser.error(“文件%s不存在使用--help标志输入选项“%arg) else: return open(arg,'r') #_______ –

回答

1

你可以修改你的功能如下在检查它的存在后返回字符串:

def is_valid_file(parser, arg): 
     if not os.path.exists(arg): 
      parser.error("The file %s does not exist! Use the --help flag for input options." % arg) 
     else: 
      return arg 

还有一个更直接的方法:

parser.add_argument("-test", dest="testfile", required=True, 
        help="test", type=file) # file exists in python 2.x only 

parser.add_argument("-test", dest="testfile", required=True, 
        help="test", type=lambda f: open(f)) # python 3.x 

args = parser.parse_args()  
print(args.testfile.name) # name of the file from the file handle 

实际上args.testfile是文件句柄,打开通过argparser(如果没有找到异常)。你可以直接阅读。

+0

非常感谢! –

1

FileType型工厂做了大部分的代码做什么,有一个稍微不同的消息机制:

In [16]: parser=argparse.ArgumentParser() 
In [17]: parser.add_argument('-f',type=argparse.FileType('r')) 

In [18]: args=parser.parse_args(['-f','test.txt']) 
In [19]: args 
Out[19]: Namespace(f=<_io.TextIOWrapper name='test.txt' mode='r' encoding='UTF-8'>) 
In [20]: args.f.read() 
Out[20]: ' 0.000000, 3.333333, 6.666667, 10.000000, 13.333333, 16.666667, 20.000000, 23.333333, 26.666667, 30.000000\n' 
In [21]: args.f.close() 

对于它打开文件,您可以使用和关闭一个有效的名称。但是你不能在with上下文中使用它。

如果该文件不存在,它会退出使用和cant open消息。

In [22]: args=parser.parse_args(['-f','test11.txt']) 
usage: ipython3 [-h] [-f F] 
ipython3: error: argument -f: can't open 'test11.txt': [Errno 2] No such file or directory: 'test11.txt' 

FileType__call__处理错误与argparse.ArgumentTypeError

except OSError as e: 
     message = _("can't open '%s': %s") 
     raise ArgumentTypeError(message % (string, e)) 

使用这种错误的机制,并忽略你的open我建议:

def valid_file(astring): 
    if not os.path.exists(astring): 
     msg = "The file %s does not exist! Use the --help flag for input options." % astring 
     raise argparse.ArgumentTypeError(msg) 
    else: 
     return astring 

这可能是用作:

In [32]: parser=argparse.ArgumentParser() 
In [33]: parser.add_argument('-f',type=valid_file) 

In [34]: args=parser.parse_args(['-f','test11.txt']) 
usage: ipython3 [-h] [-f F] 
ipython3: error: argument -f: The file test11.txt does not exist! Use the --help flag for input options. 
An exception has occurred, use %tb to see the full traceback. 

SystemExit: 2 

In [35]: args=parser.parse_args(['-f','test.txt']) 
In [36]: args 
Out[36]: Namespace(f='test.txt') 
In [37]: with open(args.f) as f:print(f.read()) 
    0.000000, 3.333333, 6.666667, 10.000000, 13.333333, 16.666667, 20.000000, 23.333333, 26.666667, 30.000000 

http://bugs.python.org/issue13824担心FileType打开文件但没有关闭它。我提出了一个FileContext,仿照FileType,但不是打开文件,返回一个对象,可以为使用:

with arg.file() as f: 
    f.read() 

它会做的文件存在或creatablity测试,而无需实际打开或创建文件。这是一个更复杂的解决方案。