如果我使用可选参数输入来调用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 权限