在Python中拥有唯一标识符的正确方法?

时间:2009-11-05 01:10:39

标签: python identifier

基本上,我有一个列表:[START, 'foo', 'bar', 'spam', eggs', END],后面需要START / END标识符,以便稍后进行比较。现在,我把它设置成这样:

START = object()
END = object()

这很好用,但是它遇到了不能使用酸洗的问题。我试着按照以下方式做到这一点,但这似乎是一种实现这个目标的可怕方法:

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

有人可以分享更好的方法吗?另外,我上面设置的例子只是对另一个问题的过度简化。

5 个答案:

答案 0 :(得分: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通过普遍性,简洁性和较轻的权重获胜。

答案 1 :(得分: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))

答案 2 :(得分:1)

如果你的列表没有字符串,我只使用“start”,“end”,因为Python因为实习而进行比较O(1)。

如果你确实需要字符串,而不是元组,那么完整的cheapskate方法是:

[("START",), 'foo', 'bar', 'spam', eggs', ("END",)]
PS:我确定你的名单是之前的数字,而不是字符串,但我看不到任何修改,所以我一定想象它

答案 3 :(得分:1)

实际上,我喜欢你的解决方案。

前段时间我正在攻击Python模块,我希望有一个特殊的魔法值,这在其他任何地方都无法出现。我花了一些时间思考它,我提出的最好的是你使用的相同技巧:声明一个类,并使用类对象作为特殊的魔法值。

当您检查哨兵时,您当然应该使用is运算符来识别对象:

for x in my_list:
    if x is START:
        # handle start of list
    elif x is END:
        # handle end of list
    else:
        # handle item from list

答案 4 :(得分:0)

我想如果你更明确地知道你需要什么,这可能会更容易回答,但是如果面对像这样的问题我会倾向于:

>>> START = os.urandom(16).encode('hex')
>>> END = os.urandom(16).encode('hex')

这种方法的优点,正如我所看到的那样

  • 您的标记是字符串(可以腌制或以其他方式轻松序列化,例如JSON或DB,无需任何特别的努力)
  • 非常不可能意外或故意碰撞
  • 将序列化和反序列化为相同的值,即使在进程重新启动过程中也是如此(我认为)不是object()或空类的情况。

缺点(?)

  • 每次新选时,他们都会完全不同。 (这个好坏取决于你没有提供的细节,我想)。