【问题标题】:How do I pass arbitrary arguments in Python如何在 Python 中传递任意参数
【发布时间】:2020-03-03 16:55:09
【问题描述】:

在我必须做的任务中,我应该创建一个替代“rm”命令的方法。我必须传递可变数量的参数,例如,

$ rm.py /path/to/some/file ./somefile someotherfile
$ rm.py /path/to/some/file ./somefile someotherfile -r
$ rm.py -r /path/to/some/file ./somefile someotherfile
$ rm.py *.java

-r 参数可以在任何地方作为任何参数传递。 -r 的含义与使用常规“rm”命令时的含义相同。 它递归地删除一个目录及其内容。

它运行脚本,并且给出的任何路径都像

rm.py /path/to/some/file

然后将其移动到输出目录 '~/rm_trash' 如果有重复,我也担心。

但首先,我在理解如何处理它时遇到了一些麻烦。 我是否应该在 for 循环中进行处理,如果其中一个参数等于“-r”,则从那里开始?

我应该导入和使用 argparse 吗?

我还有一些问题,但我想先处理一下我上面问的问题。

不得不再次发布,仍然不明白我如何获得除“r”之外的任意数量参数的具体参数

【问题讨论】:

  • 当前代码现在如何检查参数?您是在检查 sys.argv 的元素(出于教学原因)还是使用参数解析库?
  • 我早些时候发布了这个,并被告知要查看 argparse 库,我确实认为它有一些帮助。但我很好,不知道我是否正确使用它,也不知道我是否可以在作业中使用它。一位同行告诉我,首先要在一个 foror 循环中查找“-r”参数。但是怎么做?
  • 到目前为止您尝试过什么?发布一些现有代码将有助于提供更好的答案。此外,StackOverflow 用户将无法确定在作业中使用 argparse 是否是一个好主意。
  • @NicholasM 是的,我知道,好吧,目前我没有任何代码,只是伪代码,我不知道我是否可以发布。是的,可能的重复是我的帖子已关闭并且在关闭时没有帮助我。

标签: python arguments command-line-arguments argparse


【解决方案1】:

我会使用 argparse,因为您可以指定乱序操作:

https://docs.python.org/3/library/argparse.html

【讨论】:

  • 即使说我不使用“-r”命令,argparse 也应该工作吗?或者如果我只调用一个或两个或三个参数等?
  • 只要是可选参数,只有在你指定时才会使用。 argparse 非常强大,它应该能够处理你所有的情况。这是操作文档:docs.python.org/3/howto/argparse.html
  • 谢谢,让我继续阅读。如果它是文件、目录、/path/to/file,那么其他参数呢?
【解决方案2】:

如果您不想使用argparse,或者不能用于分配目的,您可以查看sys.argv

is_recursive = any(arg == '-r' for arg in sys.argv)  

# `paths` will be a list of all other arguments
paths = [arg for arg in sys.argv if arg != '-r']   

【讨论】:

  • 谢谢,在那种情况下让我试试这个,其他路径呢,如果我想使用 shutil 移动文件/目录,我需要一个源,我应该能够操作您在上面发布的代码也是如此,对吗?
【解决方案3】:

定义一个解析函数,它查找'-r'字符串:

def parse(alist, astr='-r'):
    try:
        idx = alist.index(astr)
        r = alist.pop(idx)
        return True, alist
    except ValueError:
        return False, alist

如果我们这样做

import sys
r, rest = parse(sys.argv[1:])

应该为r 提供一个真/假值,以及一个文件名列表。在其余代码中使用它们。

测试:

In [326]: list1 = 'rm.py /path/to/some/file ./somefile someotherfile'.split()   
In [329]: r, rest = parse(list1[1:])                                            
In [330]: r, rest                                                               
Out[330]: (False, ['/path/to/some/file', './somefile', 'someotherfile'])

In [331]: list2 = 'rm.py /path/to/some/file ./somefile someotherfile -r'.split()                                                                     
In [332]: r, rest = parse(list2[1:])                                            
In [333]: r, rest                                                               
Out[333]: (True, ['/path/to/some/file', './somefile', 'someotherfile'])

为了说明出现“-r”时会发生什么:

In [335]: list2.index('-r')                                                     
Out[335]: 4
In [336]: list2.pop(4)                                                          
Out[336]: '-r'
In [337]: list2                                                                 
Out[337]: ['rm.py', '/path/to/some/file', './somefile', 'someotherfile']

如果它不存在,我们会得到一个ValueError

In [338]: list1.index('-r')                                                     
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-338-807fbe60be44> in <module>
----> 1 list1.index('-r')

ValueError: '-r' is not in list

======

使用argparse的等效功能:

In [339]: import argparse                                                       
In [340]: parser = argparse.ArgumentParser()                                    
In [341]: parser.add_argument('-r', action='store_true', help='recursive flag');                                                                       
In [342]: parser.add_argument('rest', nargs='*', help='file names');            
In [343]: args = parser.parse_args(list1[1:])                                   

使用args = parser.parse_args() 读取sys.argv

结果是一个具有所需属性的namespace 对象:

In [344]: args                                                                  
Out[344]: Namespace(r=False, rest=['/path/to/some/file', './somefile', 'someotherfile'])
In [345]: args.r                                                                
Out[345]: False
In [346]: args.rest                                                             
Out[346]: ['/path/to/some/file', './somefile', 'someotherfile']

args.rargs.rest 的使用方式与上述 rrest 相同。

“-r”可以在文件名列表之前或之后。 argparse 在您想要定义更多选项(如“-r”)时变得更加有用。它还负责显示帮助消息和有意义的错误。

In [347]: parser.parse_args(['--help'])                                         
usage: ipython3 [-h] [-r] [rest [rest ...]]

positional arguments:
  rest        file names

optional arguments:
  -h, --help  show this help message and exit
  -r          recursive flag

【讨论】:

    【解决方案4】:

    为什么不使用:

    os.system( 'rm ' + ' '.join( sys.argv[1:] )
    

    并完成它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-10
      • 2023-03-15
      • 2022-06-27
      • 2021-12-13
      • 2015-04-22
      • 1970-01-01
      • 2022-11-10
      • 2023-03-12
      相关资源
      最近更新 更多