2016-09-06 2 views
0

Я хотел бы проанализировать имя файла в моем скрипте как строку, а не напрямую преобразовывать файл в объект.Аргумент: проанализировать имя файла как строку (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

Спасибо Жан-Франсуа, я написал предыдущую функцию, чтобы проверить наличие файлов, удалив это из кода решает проблему. –

+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 является дескриптором файла, открытым by 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, не открывая или создания файла. Это более сложное решение.