【问题标题】:TypeError: cannot use a string pattern on a bytes-like object - Py3TypeError:不能在类似字节的对象上使用字符串模式 - Py3
【发布时间】:2020-06-21 18:11:18
【问题描述】:

我在使用 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 python-3.x


    【解决方案1】:

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

    【讨论】:

    • 这是多语种吗?
    • @LokeshAgrawal 好的,所以您不是要尝试从 Python 2 转换到 Python 3,而是让它适用于两种语言?
    • 是的@Ted 我正在努力使它适用于两个版本
    • @LokeshAgrawal 将模式转换为字节对象将起作用
    • 其实它们差不多。我建议第二个选项的原因是因为decode 在 Python 2 中返回 Unicode 字符串,但在 Python 3 中返回字节。但是,它们与您的用例兼容。我认为第二个版本更好,因为你总是会以字节而不是不同的编码来思考。但两者可能都可以正常工作。
    猜你喜欢
    • 2014-02-21
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 2016-06-03
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多