簡體   English   中英

將多個路徑作為命令行參數傳遞的最佳實踐,以說明帶有空格的路徑

[英]Best practice to pass multiple paths as command line argument accounting for paths with spaces

背景

我正在編寫的 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 function 可通過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)

問題

處理用空格分隔並用引號括起來的多條路徑不會返回所需的結果。

所需 output

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

問題有兩個方面:

  1. 本文所述,使用~時需要使用os.path.expanduser
  2. 當您的輸入包含引號( '" )時, 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM