为何将Python代码放入函数中会抛出TypeError错误?
错误根源
你调用func.GetInstalledApps()时,result.stdout已经是字符串类型,但你仍使用str(result.stdout, 'utf-8')的方式转换——这种写法仅适用于result.stdout为bytes类型的场景,当它本身就是str时,就会触发TypeError: a bytes-like object is required, not 'str'。
两种场景下result.stdout类型不同的核心原因:你在交互式shell中执行import script后,修改了subprocess.run的默认行为(比如通过functools.partial给subprocess.run默认添加了text=True或encoding='utf-8'参数),导致后续调用subprocess.run时,stdout会自动解码为字符串。而script.py是在修改默认参数前导入执行的,当时result.stdout是bytes类型,因此str(bytes, 'utf-8')能正常运行。
解决方法
以下几种方式可确保代码在任何环境下正常运行:
1. 明确指定编码,直接返回字符串
在subprocess.run中添加encoding='utf-8'参数,result.stdout会直接是字符串,无需额外转换:
def GetInstalledApps(): result = subprocess.run(["flatpak", "list", "--columns=application", "--app"], check=True, stdout=subprocess.PIPE, encoding='utf-8') somestring = result.stdout print(somestring)
2. 使用text=True参数(Python 3.7+)
效果与指定encoding一致,写法更简洁:
def GetInstalledApps(): result = subprocess.run(["flatpak", "list", "--columns=application", "--app"], check=True, stdout=subprocess.PIPE, text=True) somestring = result.stdout print(somestring)
3. 兼容bytes和str两种类型
如果无法确定result.stdout的类型,可先判断再处理:
def GetInstalledApps(): result = subprocess.run(["flatpak", "list", "--columns=application", "--app"], check=True, stdout=subprocess.PIPE) if isinstance(result.stdout, bytes): somestring = result.stdout.decode('utf-8') else: somestring = result.stdout print(somestring)
额外建议:转换bytes为字符串时,优先使用
decode('utf-8')而非str(bytes, 'utf-8'),前者可读性与规范性更好。
内容的提问来源于stack exchange,提问作者Gwendal

