小编Ste*_*eve的帖子

python argparse - 带选项的可选append参数

我有一个脚本,我要求用户提供要执行的预定义操作的列表.我还希望能够在用户没有定义任何内容时采用特定的操作列表.然而,似乎试图将这两者结合在一起是不可能的.

当用户不提供参数时,他们会收到默认选项无效的错误

acts = ['clear','copy','dump','lock']
p = argparse.ArgumentParser()
p.add_argument('action', nargs='*', action='append', choices=acts, default=[['dump', 'clear']])
args = p.parse_args([])
>>> usage: [-h] [{clear,copy,dump,lock} [{clear,copy,dump,lock} ...]]
: error: argument action: invalid choice: [['dump', 'clear']] (choose from 'clear', 'copy', 'dump', 'lock')
Run Code Online (Sandbox Code Playgroud)

当它们确定一组动作时,结果命名空间将用户的动作附加到默认值,而不是替换默认值

acts = ['clear','copy','dump','lock']
p = argparse.ArgumentParser()
p.add_argument('action', nargs='*', action='append', choices=acts, default=[['dump', 'clear']])
args = p.parse_args(['lock'])
args
>>> Namespace(action=[['dump', 'clear'], ['dump']])
Run Code Online (Sandbox Code Playgroud)

python argparse

17
推荐指数
3
解决办法
2万
查看次数

python - 返回默认值

我希望模仿内置函数(如getattr)的行为,允许用户指定"默认"返回值.我最初的尝试就是这样做

def myfunc(foo, default=None):
    # do stuff
    if (default is not None):
        return default
    raise SomeException()
Run Code Online (Sandbox Code Playgroud)

问题是,如果用户想要None成为他们的返回值,则此函数会引发异常.第二次尝试:

def myfunc(foo, **kwargs):
    # do stuff
    if ('default' in kwargs):
        return kwargs['default']
    raise SomeException()
Run Code Online (Sandbox Code Playgroud)

这解决了上述问题并允许用户指定任意值,但引入了一个烦恼,即用户必须始终default=bar在其函数调用中指定; 他们不能只提供bar最后.同样,*args可以使用,但default=bar如果他们更喜欢这种语法,则会阻止用户使用.

结合*args**kwargs提供可行的解决方案,但感觉这需要付出很多努力.它还可能掩盖不正确的函数调用(例如bar = myfunc(foo, baz, default=qux))

def myfunc(foo, *args, **kwargs):
    # do stuff
    if (len(args) == 1):
        return args[0]
    if ('default' in kwargs):
        return kwargs['default']
    raise SomeException()
Run Code Online (Sandbox Code Playgroud)

有更简单的解决方案吗?(如果重要,则为python 3.2)

python return-value default-value

10
推荐指数
1
解决办法
4103
查看次数

在 with-block 中重新分配变量

是否可以在退出块之前重新分配 with-block 的对象?

具体用例

我与偶尔在传输过程中断开连接的 FTP 服务器进行交互,而 IT 不愿意对此做任何事情。作为我自己的工具的解决方法,我使用了一个包装器,它会在放弃之前重试传输几次:

def retry(conn, max_tries=3, **kwargs):
    this_try = 1
    while (this_try <= max_tries):
        try:
            # upload / download / whatever
            return conn
        except ftplib.all_errors:
            conn.quit()
            time.sleep(60)
            conn = ftplib.FTP(**kwargs)
            this_try += 1
Run Code Online (Sandbox Code Playgroud)

这个包装器工作正常,但似乎不能在with块内使用,就像可以使用普通的 FTP 连接一样。如果该except子句被击中,连接将重新建立,但在退出with块时,python 将尝试关闭原始conn,而不是新的:

with ftplib.FTP(**kwargs) as conn:
    conn = retry(conn, **kwargs)
Run Code Online (Sandbox Code Playgroud)

这可以通过自定义上下文管理器来演示,显示 python 调用__exit__()来自原始对象,即使变量在块中间重新分配:

>>> class Echo(object):
...     def __enter__(self):
...             print('entering ' + repr(self))
...             return self
...     def …
Run Code Online (Sandbox Code Playgroud)

python

5
推荐指数
1
解决办法
192
查看次数

标签 统计

python ×3

argparse ×1

default-value ×1

return-value ×1