在Python中获取唯一标识符的正确方法?

6 投票
5 回答
1440 浏览
提问于 2025-04-15 15:40

基本上,我有一个列表,内容是:[START, 'foo', 'bar', 'spam', 'eggs', END],其中的START和END这两个标识符是很重要的,因为我后面需要用它们来做比较。目前,我的设置是这样的:

START = object()
END = object()

这样做是可以的,但有个问题就是它不支持“序列化”。我尝试用另一种方式来实现,但感觉这个方法很糟糕:

class START(object):pass
class END(object):pass

有没有人能分享一个更好的方法呢?另外,我上面这个例子只是一个简化版,实际上我面临的是一个更复杂的问题。

5 个回答

1

如果你的列表里没有字符串,我会直接用“start”和“end”,因为在Python中,这样比较的速度非常快,几乎是瞬间完成的。

如果你确实需要字符串,但不需要元组的话,有个非常简单的方法:

[("START",), 'foo', 'bar', 'spam', eggs', ("END",)]

顺便说一下,我之前还以为你的列表里是数字,而不是字符串,但我看不到任何修改,所以可能是我记错了。

2

你可以定义一个 Symbol 类来处理开始(START)和结束(END)。

class Symbol:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        return isinstance(other, Symbol) and other.value == self.value

    def __repr__(self):
        return "<sym: %r>" % self.value

    def __str__(self):
        return str(self.value)

START = Symbol("START")
END = Symbol("END")

# test pickle
import pickle
assert START == pickle.loads(pickle.dumps(START))
assert END == pickle.loads(pickle.dumps(END))
10

如果你想要一个保证是唯一的对象,并且在经过“打包”和“解包”后能够恢复到完全相同的状态,那么顶层函数、类、类的实例,以及如果你在意的是 is 而不是 == 的话,列表(还有其他可变对象)都是可以的。也就是说,下面这些都可以:

# work for == as well as is
class START(object): pass
def START(): pass
class Whatever(object): pass
START = Whatever()

# if you don't care for "accidental" == and only check with `is`
START = []
START = {}
START = set()

这些选项都没有什么特别糟糕的地方,也没有哪个特别有优势(这取决于你在意 == 还是 is)。可能 def 更胜一筹,因为它更通用、更简洁,而且占用的资源更少。

撰写回答