查找 "bytes" 和 "str" 之间的所有比较

Find all comparision between "bytes" and "str"

我正在从 Python 2 -> Python 3 迁移一个大项目,"bytes" 和 "str" 之间的比较问题仅在旧代码 运行 时发现进入它并明确失败。如果它错误地通过了,我将不会知道。 一个例子:

def read_var_startaddr(self, var_name):
#__get_var_name() will return bytes
if self.__get_var_name() == var_name:
    print("do something")        
return self.__get_startaddr() 

所以我想为整个项目修复这个问题,而不是等到事情发生,我有两件事:

  1. 使用Notepad++:用正则表达式搜索整个项目,并用眼睛检查...确保没有意外替换发生。 Search with Notepad++
  2. 我想要创建基本运算符“==”或“!=”的包装器,目的是自动转换和比较相应的值。

我的问题: 使用选项 2,是否可以包装基本运算符,如何做以及它可能造成的影响是什么? 有没有更好的办法?

非常感谢!

可以更普遍地执行此操作的一个工具是 mypy 类型检查器;那将是相当重量级的,但它肯定会发现这些问题。

它可能会发现很多其他问题,而且它通常是对程序的重大更改,因此您必须对其进行整体评估,而不是专门针对这一问题进行评估。

也许先 2to3 试一试(我假设是你选择的标签)。它内置于 Python 3 中,可能会为您节省大量时间。


特别是对于数字 2,您可以覆盖对象中的 dunder 方法 __eq__,并改用它。像这样:

class Item:
    def __init__(self, item):
        if isinstance(item, bytes):
            self._item = item
        elif isinstance(item, str):
            self._item = bytes(item, 'utf-8')
        elif isinstance(item, int):
            self._item = bytes(str(item), 'utf-8')
        else:
            raise Exception("Item must be of type bytes, str, or int.")

    def __eq__(self, other):
        if isinstance(other, bytes):
            return self._item == other
        elif isinstance(other, str):
            return self._item.decode("utf-8") == other
        elif isinstance(other, int):
            if self._item.isdigit():
                return int(self._item) == other
            else:
                raise Exception("Cannot compare non-int to int.")

那么以下所有方法都有效:

item = Item("hello")

item == "hello"  # True
item == b"hello" # True
item = Item(100)

item == 100 # True
item == "100" # True
item == b"100" # True

请注意,所有对象 Item 现在都可以与我们编写的新 __eq__ 进行比较。如果您想知道 "is there a way to modify ALL == comparison signs",答案是……从技术上讲是的,但我向您保证这不值得。您将不得不处理 ast 模块并创建一些非常混乱的代码。


您还可以更简单地创建一个函数 compare_str_bytes(),它使用上面的一些代码来相应地比较字节和字符串。