python - TypeError:不能在类似字节的对象上使用字符串模式 - Py3
问题描述
我在使用 Python3 时遇到以下错误,但该函数在 Python2 中运行良好
from subprocess import Popen, PIPE, STDOUT
import re
def source_shell():
pattern = re.compile('^(w+)=(.*)$')
cmd = 'ls /etc/fstab /etc/non-existent-file'
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
for line in p.stdout:
line = line.strip()
if not pattern.match(line):
print("hurray")
source_shell()
Traceback (most recent call last):
File "main.py", line 15, in <module>
source_shell()
File "main.py", line 12, in source_shell
if not pattern.match(line):
TypeError: cannot use a string pattern on a bytes-like object
在这里进行什么最安全的更改,这样它就不会破坏任何现有的东西?
多语言答案表示赞赏。
解决方案
字符串在 Python 2 中是字节对象,而在 Python 3 中它们是字符串对象。您返回的结果Popen
是一个字节对象,因此您必须先将其转换为字符串(使用该decode
方法),然后再将其与您的模式匹配。
from subprocess import Popen, PIPE, STDOUT
import re
def source_shell():
pattern = re.compile('^(w+)=(.*)$')
cmd = 'ls /etc/fstab /etc/non-existent-file'
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
for line in p.stdout:
line = line.strip().decode() # Decode the bytes-object to a string.
if not pattern.match(line):
print("hurray")
source_shell()
如果您希望它同时适用于 Python 2 和 Python 3,我建议将模式转换为匹配字节对象而不是字符串。
from subprocess import Popen, PIPE, STDOUT
import re
def source_shell():
pattern = re.compile(b'^(w+)=(.*)$') # Compile to bytes.
cmd = 'ls /etc/fstab /etc/non-existent-file'
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
for line in p.stdout:
line = line.strip()
if not pattern.match(line):
print("hurray")
source_shell()
推荐阅读
- c++ - 从 MSVC 2013 (C++11) 迁移到 MSVC 2019 (C++17) 时,std::vector::insert() 停止工作
- html - 在导航栏中创建活动状态箭头
- python - 如何在numpy数组中应用条件语句?
- java - 我想从 Firebase 存储中删除特定用户数据文件夹
- python - 如何捕获或保存所有 gRPC 流
- node.js - 全局安装的 npm-package 未运行
- node.js - 从没有排序键的 dynamodb 批量条件删除
- hibernate - JPA 一对一与非主键给出 Unable to find column with logical name error
- flutter - 如何将 setstate 作为参数传递给类方法
- python - 为什么 path.abspath 不生成依赖库的绝对路径?