Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I put docstrings on Enums?

Python 3.4 has a new enum module and Enum data type. If you are unable to switch to 3.4 yet, Enum has been backported.

Since Enum members support docstrings, as pretty much all python objects do, I would like to set them. Is there an easy way to do that?

like image 526
Ethan Furman Avatar asked Oct 12 '13 04:10

Ethan Furman


People also ask

Where do you put docstrings?

Module docstrings are placed at the top of the file even before any imports. Module docstrings should include the following: A brief description of the module and its purpose. A list of any classes, exception, functions, and any other objects exported by the module.

How do you do docstrings?

The doc string line should begin with a capital letter and end with a period. The first line should be a short description. If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description.

How can docstrings be accessed?

Docstrings are accessible from the doc attribute (__doc__) for any of the Python objects and also with the built-in help() function. An object's docstring is defined by including a string constant as the first statement in the object's definition.

Can docstrings be assigned to variables?

Yes, you can do that! You can actually 'document' lambdas and variables in a module by attaching docstrings to them.

What is an enum in C?

C# Enums. An enum is a special "class" that represents a group of constants (unchangeable/read-only variables). To create an enum, use the enum keyword (instead of class or interface), and separate the enum items with a comma: Example. enum Level { Low, Medium, High } You can access enum items with the dot syntax:

How do I create an enum in JavaScript?

While the keys must be strings, as with JavaScript objects in general, the values for enum members are often auto-incremented numbers that mainly serve to distinguish one member from the other. Enums with only number values are called numeric enums. To create a numeric enum, use the enum keyword, followed by the name of the enum.

How to use string-based enums?

In summary, to make use of string-based enum types, we can reference them by using the name of the enum and their corresponding value, just as you would access the properties of an object. At runtime, string-based enums behave just like objects and can easily be passed to functions like regular objects.

How to access enum items in a list?

You can access enum items with the dot syntax: Level myVar = Level.Medium; Console.WriteLine(myVar); Try it Yourself » Enum is short for "enumerations", which means "specifically listed".


2 Answers

Yes there is, and it's my favorite recipe so far. As a bonus, one does not have to specify the integer value either. Here's an example:

class AddressSegment(AutoEnum):
    misc = "not currently tracked"
    ordinal = "N S E W NE NW SE SW"
    secondary = "apt bldg floor etc"
    street = "st ave blvd etc"

You might ask why I don't just have "N S E W NE NW SE SW" be the value of ordinal? Because when I get its repr seeing <AddressSegment.ordinal: 'N S E W NE NW SE SW'> gets a bit clunky, but having that information readily available in the docstring is a good compromise.

Here's the recipe for the Enum:

class AutoEnum(enum.Enum):
    """
    Automatically numbers enum members starting from 1.

    Includes support for a custom docstring per member.
    """
    #
    def __new__(cls, *args):
        """Ignores arguments (will be handled in __init__."""
        value = len(cls) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj
    #
    def __init__(self, *args):
        """Can handle 0 or 1 argument; more requires a custom __init__.

        0  = auto-number w/o docstring
        1  = auto-number w/ docstring
        2+ = needs custom __init__

        """
        if len(args) == 1 and isinstance(args[0], (str, unicode)):
            self.__doc__ = args[0]
        elif args:
            raise TypeError('%s not dealt with -- need custom __init__' % (args,))

And in use:

>>> list(AddressSegment)
[<AddressSegment.ordinal: 1>, <AddressSegment.secondary: 2>, <AddressSegment.misc: 3>, <AddressSegment.street: 4>]

>>> AddressSegment.secondary
<AddressSegment.secondary: 2>

>>> AddressSegment.secondary.__doc__
'apt bldg floor etc'

The reason I handle the arguments in __init__ instead of in __new__ is to make subclassing AutoEnum easier should I want to extend it further.

like image 197
Ethan Furman Avatar answered Oct 31 '22 18:10

Ethan Furman


Anyone arriving here as a google search:

For many IDE's now in 2022, the following will populate intellisense:

class MyEnum(Enum):
    """
    MyEnum purpose and general doc string
    """

    VALUE = "Value"
    """
    This is the Value selection. Use this for Values
    """
    BUILD = "Build"
    """
    This is the Build selection. Use this for Buildings
    """

Example in VSCode:

enums with doc strings

popping in intellisense

like image 34
lynkfox Avatar answered Oct 31 '22 20:10

lynkfox