首页 > 解决方案 > 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

在这里进行什么最安全的更改,这样它就不会破坏任何现有的东西?

多语言答案表示赞赏。

标签: pythonpython-3.x

解决方案


字符串在 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()

推荐阅读