What I want out a Symbol type in Python

August 7, 2011

Back in OptionalArgumentsIssue, I wrote that special unique sentinel values were one of the cases where it would be nice to have a real symbol type in Python (ideally including syntactic support). This raises the question of how such a type would behave and what sort of special support it needs.

Unfortunately, what I really want requires language support. Without it, the best we can do is something like this:

>>> no_arg = Symbol("no_arg")
>>> print no_arg
>>> no_arg is Symbol("no_arg")

This gives us unique named objects and lets us us dump the symbol's name (if we gave it one) to help with debugging, but that's it. What we really want is not to have to repeat the symbol's name when we create it and for symbols to be unique in the current module; ideally there would be a less verbose syntax for creating symbols, too.

(We don't want named symbols to be globally unique, because that risks confusing my module's no_arg symbol with your module's no_arg symbol; implicit global namespaces are a bad idea. At the same time fully unique named symbols are somewhat absurd, as illustrated here. Module unique symbols are a reasonable compromise since we can say they correspond reasonably well to module level variables.)

I believe that in theory we can create module unique named symbols and mostly avoid repetition in pure Python code. However it would require relatively ugly hacks behind the back of CPython, hacks that would surprise people reading code that used symbols and not be fully reliable. To do this properly you really need interpreter support, and that should really come with special syntax so that people understand how special these symbols are.

(Unfortunately I'm not sure that Ruby's :name syntax for symbols would work given how Python syntax already uses : in various places.)

Sidebar: a really basic Symbol class

We can construct a really basic Symbol type fairly simply:

class Symbol(object):
  __slots__ = ('name',)
  def __init__(self, name = None):
    self.name = name

  def __repr__(self):
    if not self.name:
      return super(Symbol, self).__repr__()
    return "<Symbol: %s>" % self.name

  def __str__(self):
    if not self.name:
      return super(Symbol, self).__str__()
    return "Symbol('%s')" % self.name

In this version, named symbols are fully unique.

Written on 07 August 2011.
« Gnome 3: I'm out
An incomplete list of the ways around MAC address blocking »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Aug 7 01:18:16 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.