如何从 python 中的 **kwargs 参数中排除可选参数?

How to exclude an optional argument out of the **kwargs parameter in python?

如果我使用可选参数输入来调用 subprocess.Popen(command, **kwargs) 我在 PyCharm 中遇到一个有趣的检查警告,当我 .communicate() 他 return 并且想要.decode('utf8') 输出。

代码:

def my_call(command, **kwargs):
    process = subprocess.Popen(command, **kwargs)
    out, err = process.communicate()
    return out.decode('utf8'), err.decode('utf8') if err else err  # err could be None

检查警告:

Unresolved attribute reference 'decode' for class 'str'

“解决方法”:

由于 .communicate() 的默认输出是 bytestring (as described here) 如果不使用 encoding 作为可选参数调用函数,则应该不是运行时问题.尽管如此,我对此并不满意,因为将来这可能会发生并导致 AttributeError: 'str' object has no attribute 'decode'

直接的答案是围绕解码参数进行 if-case 或 try-catch-operation,如下所示:

if 'encoding' in kwargs.keys():
    return out, err
else:
    return out.decode('utf8'), err.decode('utf8') if err else err

或者:

try:
    return out.decode('utf8'), err.decode('utf8') if err else err
catch AttributeError:
    return out, err

但是我不会以这种方式摆脱检查警告。

那么如何从 **kwargs 参数中排除可选参数以消除检查警告?

忽略未解决的引用问题不是一个选项。 我尝试将编码参数设置为默认 None:subprocess.Popen(command, encoding=None, **kwargs),但没有用。

Python 中的 return 类型是硬编码的,不依赖于提供给函数的输入参数(至少据我所知)。因此,将输入参数更改为 subprocess.Popen(command, encoding=None, **kwargs) 不会对函数的预期 return 类型产生任何影响。要消除警告,我的建议是将 typing 与 try-catch 块结合使用:

def my_call(command, **kwargs):
    process = subprocess.Popen(command, **kwargs)
    err: bytes
    out: bytes 
    out, err = process.communicate()
    try:
        return out.decode('utf8'), err.decode('utf8') if err else err
    catch AttributeError:
        # Optionally throw/log a warning here
        return out, err

或者,您可以使用一个版本,其中您将 if 条件与 isinstance(err,bytes) and isinstance(out, bytes) 一起使用,这也可能会解决警告并且不会引发错误,但在 Python你请求原谅而不是许可EAFP