In Python, there are conventions for single leading underscore, double leading underscore, double leading + double trailing underscore, and single trailing underscore. Many of those are outlined in the answers at What is the meaning of a single- and a double-underscore before an object name?.
But what is the meaning or convention for single leading + single trailing underscore? I've first seen their use in the enum
module:
8.13.15.3.2. Supported
_sunder_
names
_name_
– name of the member_value_
– value of the member; can be set / modified in new_missing_
– a lookup function used when a value is not found; may be overridden_ignore_
– a list of names, either as a list() or a str(), that will not be transformed into members, and will be removed from the final class_order_
– used in Python 2/3 code to ensure member order is consistent (class attribute, removed during class creation)_generate_next_value_
– used by the Functional API and by auto to get an appropriate value for an enum member; may be overridden
I have not seen such single-leading-single-trailing underscore sunder names before. Are they treated in any special way, or otherwise have an implied meaning that is distinct from any of the other underscore-related naming conventions? How are they different from having no underscores at all?
They are not treated in any special way. They are being used by the enum module so as to
e.g.
class Status(Enum):
alive = auto()
dead = auto()
missing = auto()
You can see that Status.missing
and Status._missing_
are different objects. If the Enum method _missing_
were named missing
, we would have overridden it.
not appear as private. The name _value
in python is considered private. To express that these are not private (which again, a user might want an enum value to be private), they are instead given sunder names
other alternatives such as __double_leading_underscore
and __dunder__
also have special meanings in python as you stated above. _sunder_
methods in Enum
act something like the __dunder__
protocols of pure python, but aren't reserved by the language.
Basically, it's an option to avoid attribute name conflicts without giving the wrong impression.