Symbols

Using sets

There are different ways of defining symbols. You can do it very simply with sets:

>>> s = set("abc", "def", "ghi")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: set expected at most 1 arguments, got 3
>>> s = set(["abc", "def", "ghi"])
>>> s
set(['abc', 'ghi', 'def'])
>>> "abc" in s
True
>>>

If you are using python 3.X, the notation:

Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 in {1,2,3}
True
>>>

is very effective for working with symbols. Use immutable sets.

Using namespaces

Here is a real world example from the tiramisu library

# ____________________________________________________________
class _NameSpace(object):
    """convenient class that emulates a module
    and builds constants (that is, unique names)
    when attribute is added, we cannot delete it
    """

    def __setattr__(self, name, value):
        if name in self.__dict__:  # pragma: optional cover
            raise ConstError(_("can't rebind {0}").format(name))
        self.__dict__[name] = value

    def __delattr__(self, name):  # pragma: optional cover
        if name in self.__dict__:
            raise ConstError(_("can't unbind {0}").format(name))
        raise ValueError(name)


class GroupModule(_NameSpace):
    "emulates a module to manage unique group (OptionDescription) names"
    class GroupType(str):
        """allowed normal group (OptionDescription) names
        *normal* means : groups that are not master
        """
        pass

    class DefaultGroupType(GroupType):
        """groups that are default (typically 'default')"""
        pass

    class MasterGroupType(GroupType):
        """allowed normal group (OptionDescription) names
        *master* means : groups that have the 'master' attribute set
        """
        pass


class OwnerModule(_NameSpace):
    """emulates a module to manage unique owner names.

    owners are living in `Config._cfgimpl_value_owners`
    """
    class Owner(str):
        """allowed owner names
        """
        pass

    class DefaultOwner(Owner):
        """groups that are default (typically 'default')"""
        pass


class MultiTypeModule(_NameSpace):
    "namespace for the master/slaves"
    class MultiType(str):
        pass

    class DefaultMultiType(MultiType):
        pass

    class MasterMultiType(MultiType):
        pass

    class SlaveMultiType(MultiType):
        pass


# ____________________________________________________________
def populate_groups():
    """populates the available groups in the appropriate namespaces

    groups.default
        default group set when creating a new optiondescription

    groups.master
        master group is a special optiondescription, all suboptions should be
        multi option and all values should have same length, to find master's
        option, the optiondescription's name should be same than de master's
        option

    groups.family
        example of group, no special behavior with this group's type
    """
    groups.default = groups.DefaultGroupType('default')
    groups.master = groups.MasterGroupType('master')
    groups.family = groups.GroupType('family')


def populate_owners():
    """populates the available owners in the appropriate namespaces

    default
        is the config owner after init time

    user
        is the generic is the generic owner
    """
    setattr(owners, 'default', owners.DefaultOwner('default'))
    setattr(owners, 'user', owners.Owner('user'))

    def addowner(name):
        """
        :param name: the name of the new owner
        """
        setattr(owners, name, owners.Owner(name))
    setattr(owners, 'addowner', addowner)

# ____________________________________________________________
# populate groups and owners with default attributes
groups = GroupModule()
populate_groups()
owners = OwnerModule()
populate_owners()