2016-09-06 104 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測試,而無需實際打開或創建文件。這是一個更復雜的解決方案。