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



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

代码:

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()的输出默认为字节串(如本文所述(,因此如果不使用encoding作为可选参数来调用函数,则不应该是运行时问题。尽管如此,我对此并不满意,因为在未来可能会发生这种情况,并导致AttributeError: 'str' object has no attribute 'decode'

简单的答案是围绕解码参数进行if case或try-catch操作,如下所示:

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中的返回类型是硬编码的,不依赖于给函数的输入参数(至少据我所知(。因此,将输入参数更改为subprocess.Popen(command, encoding=None, **kwargs)不会对函数的预期返回类型产生任何影响。为了消除这些警告,我的建议是将打字与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 权限

最新更新