Proposal for adding symbols within Python

Steven D'Aprano steve at REMOVETHIScyber.com.au
Mon Nov 14 16:50:42 EST 2005


On Mon, 14 Nov 2005 17:15:04 +0100, Pierre Barbier de Reuille wrote:

> The problem is not about having something constant !
> The main point with symbols is to get human-readable values.
> Let say you have a symbol "opened" and a symbol "closed". The state of a
> file may be one of the two.
> 
> If you have these symbols, you can ask for the state at any point and
> get something readable. If you use constants valued, typically, to
> integers, the state of your file will we 0 or 1, which does not mean
> anything.

???

Why does the byte string "\x6f\x70\x65\x6e\x65\x64" have intrinsic meaning
when the int 0 doesn't? It certainly doesn't mean anything to non-English
speakers.

If all you want is human readable byte strings, then just use them:

class MyFile:
    def open(self):
        self.state = "opened"
    def close(self):
        self.state = "closed"


You don't need special syntax to use strings as symbols, you get them for
free without all the overhead you are proposing.


> Now, if you're using an object with more than two states, and moreover
> if the number of states is likely to increase during developpement, it's
> much more convenient to directly get the *meaning* of the value rather
> than the value itself (which does not mean anything).

How do you expect this to work in practice? You have an object which
has states:

obj = SomeThingComplex()

Now you want to operate on it according to the state. What do you do?

if obj.state is $closed$:
    obj.open()
elif obj.state is $opened$:
    obj.close()
elif obj.state is $full$:
    obj.make_empty()
elif obj.state is $empty$:
    obj.make_full()
else:
    # some other symbol
    raise ValueError("Unexpected state %s") % obj.state

Replace "is" with "==" and $ with " and you have strings. You still need
to know what the object state is, and the way you do that is by comparing
it to something. Whether you call that something a symbol, an enum, a
string, an int, a class, whatever, the comparison still needs to be done.


> The key point that, I think, you misunderstand is that symbols are not
> *variables* they are *values*.

Python doesn't have variables. It has names and objects.


> Well, I think a new syntax will promote the use of symbols. And as I
> think they are good practice (much better than meaningless constants)
> they should be promoted. Needless to say that in every language I know
> implementing symbols (or something close to symbols), there is an
> easy-to-use syntax associated.

Why is $closed$ better practice than "closed"?

Why is "closed" a meaningless constant and $closed$ a good symbol?


> Well, one *big* difference between short string and symbols is that the
> identity between short strings are implementation dependant, 

Then don't use identity. Who cares whether the state you are testing
against points to the same chunk of memory or not? What possible
difference will that make, except some unnecessary optimization
_possibly_ saving you one millionth of a second at runtime?

> while
> between symbols it has to be in all implementations as you will rely on
> this identity. Then, once more, strings are just one possible
> implementation for symbols and I wouldn't like to tie that much symbols
> to strings.

And ints are another possible implementation for symbols, or classes, or
enums.

obj.state = 42 is not an ideal implementation, because it is not
self-documenting, and self-documenting code is good code. But in some
contexts, it may be the right thing to do:

class MutablePolygon:
    """Define a polygon object that can grow or lose sides."""
    def __init__(self, n):
        """Create a new polygon with n sides."""
        self.state = n
    def grow_side(self):
        self.state += 1
    def lose_side(self):
        self.state -= 1

Compare that with something like this:

class MutablePolygon:
    """Define a polygon object that can grow or lose sides."""
    def __init__(self, n):
        """Create a new polygon with n sides."""
        if n == 1:
            self.state = $one$
        elif n == 2:
            self.state = $two$
        elif n == 3:
            self.state = $three$
        elif n ...


-- 
Steven.




More information about the Python-list mailing list