Pythonic way around Enums
<p>What is the <em>pythonic</em> way to tell the caller of a function what values a given parameter supports?</p>

<p>He is an example for PyQt (for GUI). Say I have a checkbox, </p>

<pre><code>class checkbox(object):
    ....
    def setCheckState(self, value):
        ....
</code></pre>

<p>Here, <code>setCheckState()</code> should only expect <strong>checked</strong> or <strong>unchecked</strong>.</p>

<p>PyQt uses a built-in enumeration (i.e. <code>Qt.Checked</code> or <code>Qt.Unchecked</code>), but this is awful. I am constantly in the documentation looking for the enum for the object I am working with.</p>

<p>Obviously PyQt is written in an <em>unpythonic</em> C++ sytle. How <em>should</em> this or a similar problem be handled in Python? According to <a href="https://www.python.org/dev/peps/pep-0435/" rel="nofollow">PEP 435</a>, enums seem to be a recent addition to the language and for very specific applications, so I would assume there is/was a better way to handle this?</p>

<p>I want to make the code I write easy to use when my functions require specific parameter values--almost like a combobox for functions.</p>

<p>The <em>One Obvious Way</em> is function annotations.</p>

<pre><code>class CheckBox(enum.Enum):
    Off = 0
    On = 1

def setCheckState(self, value: CheckBox):
    ...
</code></pre>

<p>This says quite clearly that <code>value</code> should be an instance of <code>CheckBox</code>.  Having <code>Enum</code> just makes that a bit easier.</p>

<p>Annotations themselves aren't directly supported in 2.7, though.  Common workarounds include putting that information in the function doc string (where various tools can find it) or in comments (as we already knew).</p>

<p>If looking for a method for your own code: use an annotating decorator.  This has the advantage of continuing to work in 3+:</p>

<pre><code>class annotate(object):
    def __init__(self, **kwds):
        self.kwds = kwds
    def __call__(self, func):
        func.__annotations__ = self.kwds

@annotate(value=CheckBox)
def setCheckState(self, value):
    ...
</code></pre>

<p>To be a robust decorator it should check that the contents of <code>kwds</code> matches the function parameter names.</p>

python python-2.7 function parameters enums