Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way of having a unique identifier in Python?

Basically, I have a list like: [START, 'foo', 'bar', 'spam', eggs', END] and the START/END identifiers are necessary for later so I can compare later on. Right now, I have it set up like this:

START = object()
END = object()

This works fine, but it suffers from the problem of not working with pickling. I tried doing it the following way, but it seems like a terrible method of accomplishing this:

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

Could anybody share a better means of doing this? Also, the example I have set up above is just an oversimplification of a different problem.

like image 455
Evan Fosmark Avatar asked Nov 05 '09 01:11

Evan Fosmark


2 Answers

If you want an object that's guaranteed to be unique and can also be guaranteed to get restored to exactly the same identify if pickled and unpickled right back, top-level functions, classes, class instances, and if you care about is rather than == also lists (and other mutables), are all fine. I.e., any of:

# 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()

None of these is terrible, none has any special advantage (depending if you care about == or just is). Probably def wins by dint of generality, conciseness, and lighter weight.

like image 130
Alex Martelli Avatar answered Nov 08 '22 17:11

Alex Martelli


You can define a Symbol class for handling START and 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))
like image 43
Anand Chitipothu Avatar answered Nov 08 '22 18:11

Anand Chitipothu