在Python中获取唯一标识符的正确方法?
基本上,我有一个列表,内容是:[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
更胜一筹,因为它更通用、更简洁,而且占用的资源更少。