简体   繁体   English

你如何使用 argparse 获取程序的名称?

[英]How do you get the name of the program using argparse?

I am using argparse to parse command line arguments.我正在使用argparse来解析命令行参数。 While going through the documentation forargparse I could only see a provision to use a different program name.在浏览argparse的文档时,我只能看到使用不同程序名称的规定。

I want to be able to use the default program name without having to import sys .我希望能够使用默认程序名称而不必导入sys There is nothing in argparse , as far as I can see, that will return the program name.据我所知, argparse中没有任何内容会返回程序名称。

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()

print(dir(args))

And here's the output:这是输出:

['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs']

Is there any other way of retrieving the program name without having to import the sys module?有没有其他方法可以在不必导入sys模块的情况下检索程序名称?

ArgumentParser instances have a prog attribute which I think is what you want. ArgumentParser实例有一个prog属性,我认为这是您想要的。

import argparse

parser = argparse.ArgumentParser()
print('parser.prog: {}'.format(parser.prog))

I discovered this by reading the module's source code in Lib/argparse.py —specifically looking at the class ArgumentParser definition .我通过阅读Lib/argparse.py模块的源代码发现了这一点——特别是查看class ArgumentParser 定义 Since the attribute's name doesn't start with an underscore character, I assume it's public.由于属性的名称不以下划线字符开头,因此我假设它是公开的。

Update更新

I see that, nowadays at least, that the prog attribute of ArgumentParser instance is (or has been since this question was asked) documented in both Python 2's documentation and Python 3's documentation .我看到,至少现在, ArgumentParser实例的prog属性已经(或自从提出这个问题以来)记录在Python 2's documentationPython 3's documentation 中

So, yes, it's definitely public, and in both versions, if it is not supplied as a keyword argument when creating the ArgumentParser , it defaults to prog = _os.path.basename(_sys.argv[0]) (where _os and _sys are private argparse module attributes that correspond to their non-underscore-prefixed counterparts. Note that because of the use of os.basename() , this will only be the script's filename, not the complete path to it that may (it's OS dependent) have been in sys.argv[0] .所以,是的,它绝对是公开的,并且在两个版本中,如果在创建ArgumentParser时它没有作为关键字参数提供,它默认为prog = _os.path.basename(_sys.argv[0]) (其中_os_sys是私有的argparse模块属性,对应于它们的非下划线前缀对应物。请注意,由于使用os.basename() ,这将只是脚本的文件名,而不是它可能的完整路径(它取决于操作系统)已经在sys.argv[0]

Of course the correct way would be:当然正确的做法是:

>>> import sys
>>> print sys.argv[0]
    scripts/script.py

But let's assume for a moment you have a good reason that prevents you to import sys but allows you to import argparse .但是让我们暂时假设您有充分的理由阻止您import sys但允许您import argparse

martineau has done a wonderful job discovering prog , let's try it: martineau在发现prog方面做得很好,让我们试试看:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> print parser.prog
    script.py

As noted by hpaulj , this only has the filename and not the full path like sys.argv[0] because the module argparse.py is using prog = os.path.basename(sys.argv[0]) .正如hpaulj所指出的,这只有文件名,而不是像sys.argv[0]这样的完整路径,因为模块argparse.py正在使用prog = os.path.basename(sys.argv[0])

But argparse must use sys , so it needs to be accessible in argparse namespace.但是argparse必须使用sys ,因此它需要在argparse命名空间中可访问。 Let's check it:让我们检查一下:

>>> import argparse
>>> print argparse.__dict__
    { ..., '_sys': <module 'sys' (built-in)>, ... }

Here it is!这里是! Let's try to use _sys :让我们尝试使用_sys

>>> import argparse
>>> print argparse._sys.argv[0]
    scripts/script.py

You are using sys !您正在使用sys Of course, but I haven't imported it, only argparse , that was the question!当然,但我没有导入它,只有argparse ,这就是问题所在!

Of course this has a number of contraindications:当然,这有许多禁忌症:

  • You should not use variables prefixed by _ or __ of other namespaces, they are used internally .您不应该使用以___为前缀的其他命名空间的变量,它们是在内部使用的。
  • You should not rely on imports of other modules, they may change.你不应该依赖其他模块的导入,它们可能会改变。
  • You should not rely on undocumented api, they may change.您不应该依赖未记录的 api,它们可能会改变。

tl;dr tl;博士

This was fun, but just stick to import sys until argparse releases an api to access sys.argv[0] .这很有趣,但只要坚持import sys直到argparse发布一个 api 来访问sys.argv[0]

%(prog) from inside argparse help texts %(prog)来自argparse帮助文本

This is a common use case when you want to give an example of how to use the command within the help itself.当您想举例说明如何在帮助本身中使用命令时,这是一个常见用例。

main.py主文件

#!/usr/bin/env python3
import argparse
parser = argparse.ArgumentParser(
        description="Do something cool. My name is: %(prog)s",
    epilog="""
This is how you do it:

    %(prog)s yourarg
""",
    formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument('somearg', help='also works here: %(prog)s')
args = parser.parse_args()

Then:然后:

./main.py -h

gives:给出:

usage: main.py [-h] somearg

Do something cool. My name is: main.py

positional arguments:
  somearg     also works here: main.py

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

This is how you do it:

    main.py yourarg

One advantage over sys.argv[0] is that the message stays unchanged no matter where you call it from:sys.argv[0]相比的一个优势是,无论您从何处调用消息,消息都保持不变:

cd ..
./mydir/main.py

Documented at: https://docs.python.org/3/library/argparse.html#prog记录在: https : //docs.python.org/3/library/argparse.html#prog

Note that the program name, whether determined from sys.argv[0] or from the prog= argument, is available to help messages using the %(prog)s format specifier.请注意,无论是从sys.argv[0]还是从prog=参数确定的程序名称,都可用于使用%(prog)s格式说明符的帮助消息。

Tested on Python 3.5.2.在 Python 3.5.2 上测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM