PS: see also on the topic: http://en.wikipedia.org/wiki/Enumerated_type
On Thu, 18 Feb 2010 10:13:33 +0100 spir <[email protected]> wrote: > Hello, > > I was lately implementing a kind of "pure symbol" type. What I call pure > symbols is these kinds of constants that refer to pure "idea", so that they > have no real obvious value. We usually _arbitrarily_ give them as value an > int, a string, a boolean, an empty object: > BLACK, WHITE = False, True > GUARD_FLAG = object() > N,S,W,E = 1,2,3,4 > READ,WRITE = 'r','w' > ... > > Such symbols, especially the ones we give boolean values, often match the use > of C preprocessor flags: > #define GUARD_FLAG > ... > #ifdef GUARD_FLAG ... > When there is a set of symbols, they match Pascal enumerations: > var > direction: (N, S, W, E); > They are often used as func parameters. > f = open("foo.txt", WRITE) > The latter case is so common that numerous (built-in or third-party) > libraries define a whole load of "pure symbol" constant values to be used as > func arguments: > pattern = re.compile(format, re.MULTILINE) > > This is very heavy, indeed. But alternatives I can imagine are worse: > * Use literal (unnamed) values: illegible. > * Use unprefixed names: pollutes global namespace. > I cannot find any good solution for this issue. This is my first question. > > These pure symbol are, I guess, a very close notion to the one of "nominals" > (see http://en.wikipedia.org/wiki/Nominal_number). And in fact pascal enums > are nominal types. So, I wrote this for isolated symbols: > class Nominal(object): > count = 0 > def __init__(self, value=None): > self.type = self.__class__ > self.type.count += 1 > # no need to restrict user-provided value, if any, to natural integer > self.value = value if value is not None else self.type.count > def __str__(self): > typeName = self.type.__name__ > return "%s:(%s)" %(typeName,self.value) > x,y,z = Nominal(),Nominal(),Nominal() > print x,y,z # Nominal:(1) Nominal:(2) Nominal:(3) > > The type here can only be Nominal; and the value is not really needed, > indeed, but it can be useful in some cases. Especially, this type can be the > base of derived Nominal types, i.e. pascal-like enums. Like in Pascal, making > the instances comparable can be very handy: > def __lt__(self, other): > assert(isinstance(other, Nominal)) > return self.value < other.value > class CardSuite(Nominal): pass > club,diamond,heart,spade = CardSuite(),CardSuite(),CardSuite(),CardSuite() > print club,diamond,heart,spade # CardSuite:(4) CardSuite:(5) > CardSuite:(6) CardSuite:(7) > print(diamond < heart) # True > > An issue is that a subtupe should start with count==0. I could not find any > way to do that, so I ended up writing a subtype factory. But this goes > against the language, for the user cannot use anymore the dedicated idiom > "class CardSuite(Nominal)". Also, the type's name has to be *stupidly* passed > as argument. So, the content of the method itself clearly shows how > artificial this solution is: > @classmethod > def subtype(cls, name): > class DummyName(cls): pass > DummyName.count = 0 > DummyName.__name__ = name > return X > CardSuite = Nominal.subtype("CardSuite") > club,diamond,heart,spade = CardSuite(),CardSuite(),CardSuite(),CardSuite() > print club,diamond,heart,spade # CardSuite:(1) CardSuite:(2) > CardSuite:(3) CardSuite:(4) > print(diamond < heart) # True > > Actually, what I need is a kind of __subtype__ magic method that acts for > subtyping the same way __init__ does for instanciation. Then, I could write: > @staticmethod > def __subtype__(subtype): > subtype.count = 0 > (Note that here I do not need a classmethod, as staticmethod is enough.) > > So, do you see any other solution? (I have probably overlooked some) > And, what do you think of __subtype__? > > Denis > ________________________________ > > la vita e estrany > > http://spir.wikidot.com/ ________________________________ la vita e estrany http://spir.wikidot.com/ _______________________________________________ Tutor maillist - [email protected] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
