【问题标题】:getopt: How to enforce two options to be present?getopt:如何强制存在两个选项?
【发布时间】:2021-08-31 16:10:39
【问题描述】:

我正在尝试强制执行两个选项。 -l-p 都应该在那里,或者 -t-p 应该在那里。

opts, args = getopt.getopt(sys.argv[1:],":lt:p:c:", "listen","target","port","command"])
    
for o,a in opts:
    if o in ("-l"):
        print("Starting Listener on 0.0.0.0")
    
    elif o in ("-t"):
        if o in ("ip"):
            print("Connecting")
    
    else:
        print("Else",(o))

【问题讨论】:

  • if o in ("-l"): 可能你需要这个if ("-l") in o:
  • getopt 已经过时多年了。它只是为了向后兼容和 C 顽固分子而维护。而是使用argparse。这将允许您设置一组互斥的参数,您可以将 -l-t 放入该组中,这样就只需要其中一个。
  • 还有各种 3rd-party 模块用于处理命令行参数(clickdocopts 等)。 argparse 的好处是成为标准库的一部分。

标签: python arguments getopt


【解决方案1】:

几点说明:

  • 除非你有充分的理由,否则我建议使用 Python 的 argparse。它是标准库的一部分,灵活、易于使用和扩展,具有很好的功能(如--help),很多人都知道。

  • “强制选项”一般为discouraged from。因此,我的建议是使用一个需要具有特定格式的位置参数。

例如:

import argparse
import ipaddress

# Assuming this is about an IP address and a port.
CONN_HELP = "Connection string must have the format IP_ADDRESS:PORT."

def valid_conn_str(conn):
    """Validate the connection string passed as a positional argument"""

    # If the colon is missing, the connection string is malformatted.
    if ":" not in conn:
        raise argparse.ArgumentTypeError(CONN_HELP)

    parts = conn.split(":")

    # If there are two or more colons,
    # the connection string is malformatted.
    if len(parts) > 2:
        raise argparse.ArgumentTypeError(CONN_HELP)

    # If the port part of the connection string is not an integer,
    # the connection string is malformatted.
    try:
        port = int(parts[1])
    except ValueError:
        raise argparse.ArgumentTypeError(CONN_HELP + " PORT must be an integer.")

    # If the port number is larger than 65535,
    # the connection string is malformatted
    if port > 65535:
        raise argparse.ArgumentTypeError(CONN_HELP + " PORT must be < 65535.")

    # You could add similar checks in order to validate the IP address
    # or whatever else you are expecting as the first part of the
    # connection string.
    #
    # If it is indeed an IP address, you could use the
    # ipaddress module for that, e.g.:

    try:
        ip_addr = ipaddress.ip_address(parts[0])
    except ValueError:
        raise argparse.ArgumentTypeError(CONN_HELP + " Invalid IP address.")

    # When all checks have passed, return the values.
    return parts[0], port


parser = argparse.ArgumentParser()
parser.add_argument(
    "conn",
    metavar="CONN_STRING",
    # Use the validator function to check the format.
    type=valid_conn_str,
    help=CONN_HELP,
)

# args contains all arguments that have been passed in.
args = parser.parse_args()

# The validation function returns two values,
# therefore connection string argument is a tuple.
target = args.conn[0]
port = args.conn[1]

print(target)
print(port)

当有人现在调用脚本时,例如:

$ my_script.py hello:world

他们会看到

usage: my_script.py [-h] CONN_STRING
my_script.py: error: argument CONN_STRING: Connection string must have the format IP_ADDRESS:PORT. PORT must be an integer.

使用有效的端口但无效的 IP 地址运行它

$ my_script.py hello:123

将给予:

usage: my_script.py [-h] CONN_STRING
my_script.py: error: argument CONN_STRING: Connection string must have the format IP_ADDRESS:PORT. Invalid IP address.

使用有效的 IP 地址和端口运行

$ my_script.py 123.123.123:123

将打印

123.123.123.123
123

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 2021-12-27
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多