Модуль Python, который я пишу, имеет некоторые функции, доступные из интерфейса командной строки через python -m fun_module -p ....
аргумент -p
, --path
принимает несколько путей. В настоящее время я определяю этот аргумент следующим образом:
parser = argparse.ArgumentParser(prog = "FunProg", add_help=True)
parser.add_argument(
"-p",
"--path",
type=utils.dir_path,
nargs = "+",
help = "Start path(s) used to conduct the search. Multiple paths should be separated with spaces.",
)
args = parser.parse_args()
dir_path
функция доступна через utils.py
файлimport os
def dir_path(str_path):
if os.path.isdir(str_path):
return str_path
else:
raise NotADirectoryError(str_path)
main
методdef main(args):
for iarg in args.path:
print("Searching path: " + iarg)
Обработка нескольких путей, разделенных пробелами и окруженных кавычками, не возвращает желаемых результатов.
python -m fun_module -p ~/Documents ~/Downloads/
Searching path: /Users/thisuser/Documents
Searching path: /Users/thisuser/Downloads/
python -m fun_module -p '~/Documents' '~/Downloads/'
Searching path: /Users/thisuser/Documents
Searching path: /Users/thisuser/Downloads/
python -m fun_module -p "~/Documents" "~/Downloads/"
Searching path: /Users/thisuser/Documents
Searching path: /Users/thisuser/Downloads/
python -m fun_module -p '~/Documents' '~/Downloads/'
Traceback (most recent call last):
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/Users/thisuser/Dev/Python/FileLister/filelister/__main__.py", line 25, in <module>
args = parser.parse_args()
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 1818, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 1851, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2060, in _parse_known_args
start_index = consume_optional(start_index)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2000, in consume_optional
take_action(action, args, option_string)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 1912, in take_action
argument_values = self._get_values(action, argument_strings)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2461, in _get_values
value = [self._get_value(action, v) for v in arg_strings]
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2461, in <listcomp>
value = [self._get_value(action, v) for v in arg_strings]
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2476, in _get_value
result = type_func(arg_string)
File "/Users/thisuser/Dev/Python/FileLister/filelister/utils.py", line 7, in dir_path
raise NotADirectoryError(str_path)
NotADirectoryError: ~/Documents
Помогает ли этот пост?
Проблема состояла из двух частей:
os.path.expanduser
при использовании ~
.'
или "
), os.path.expanduser
не будет правильно обрабатывать ввод.Чтобы решить проблемы, сначала замените кавычки пустыми строками. Используя python 3.9, это можно сделать с помощью:
for quote in ['"', "'"]:
str_path = str_path.removeprefix(quote).removesuffix(quote)
в противном случае вам придется вручную проверять и удалять:
for quote in ['"', "'"]:
if str_path.startswith(quote):
str_path = str_path[1:-1]
И тогда вы должны проверить начало тильды:
if str_path.startswith('~'):
str_path = os.path.expanduser(str_path)
Полный код:
def dir_path(str_path: str):
for quote in ['"', "'"]:
if str_path.startswith(quote):
str_path = str_path[1:-1]
if str_path.startswith('~'):
str_path = os.path.expanduser(str_path)
if os.path.isdir(str_path):
return str_path
raise NotADirectoryError(str_path)
И тестирование с любым из следующих входных данных приведет к полному пути:
python -m fun_module -p '~/Documents' '~/Downloads'
python -m fun_module -p "~/Documents" "~/Downloads"
python -m fun_module -p ~/Documents ~/Downloads
Вы пытались обернуть строку пути в
os.path.normpath(path_str)
. Посмотрите на эту функцию вместе сos.path.abspath
иos.path.relpath