[Tutor] pure symbol -- __subtype__

spir denis.spir at free.fr
Thu Feb 18 10:15:45 CET 2010


PS: see also on the topic: http://en.wikipedia.org/wiki/Enumerated_type

On Thu, 18 Feb 2010 10:13:33 +0100
spir <denis.spir at free.fr> 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/


More information about the Tutor mailing list