cardinal_pythonlib.enumlike
Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).
This file is part of cardinal_pythonlib.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Enum-based classes
See https://docs.python.org/3/library/enum.html.
The good things about enums are:
they are immutable
they are “class-like”, not “instance-like”
they can be accessed via attribute (like an object) or item (like a dict):
you can add a
@unique
decorator to ensure no two have the same valueIDEs know about them
AttrDict
’s disadvantages are:
more typing / DRY
IDEs don’t know about them
Plain old objects:
not immutable
no dictionary access – though can use
getattr()
but otherwise simpler than enums
LowerCaseAutoStringObject:
IDEs don’t understand their values, so get types wrong
from enum import Enum
class Colour(Enum):
red = 1
green = 2
blue = 3
Colour.red # <Colour.red: 1>
Colour.red.name # 'red'
Colour.red.value # 1
Colour['red'] # <Colour.red: 1>
Colour.red = 4 # AttributeError: Cannot reassign members.
Then, for fancier things below, note that:
metaclass
__prepare__(mcs, name, bases)
... prepares (creates) the class namespace
... use if you don't want the namespace to be a plain dict()
... https://docs.python.org/3/reference/datamodel.html
... returns the (empty) namespace
__new__(mcs, name, bases, namespace)
... called with the populated namespace
... makes and returns the class object, cls
class
__new__(cls)
... controls the creation of a new instance; static classmethod
... makes self
__init__(self)
... controls the initialization of an instance
- class cardinal_pythonlib.enumlike.AttrDict(*args, **kwargs)[source]
Dictionary with attribute access; see https://stackoverflow.com/questions/4984647
- class cardinal_pythonlib.enumlike.AutoNumberEnum(value)[source]
As per https://docs.python.org/3/library/enum.html (in which, called AutoNumber).
Usage:
class Color(AutoNumberEnum): red = () green = () blue = () Color.green.value == 2 # True
- class cardinal_pythonlib.enumlike.AutoNumberObject
From comment by Duncan Booth at https://www.acooke.org/cute/Pythonssad0.html, with trivial rename.
Usage:
class MyThing(AutoNumberObject): a b MyThing.a # 1 MyThing.b # 2
- class cardinal_pythonlib.enumlike.AutoStrEnum(value)[source]
Base class for
name=value
str
enums.Example:
class Animal(AutoStrEnum): horse = () dog = () whale = () print(Animal.horse) print(Animal.horse == 'horse') print(Animal.horse.name, Animal.horse.value)
See https://stackoverflow.com/questions/32214614/automatically-setting-an-enum-members-value-to-its-name/32215467 and then inherit from
StrEnum
rather thanEnum
.
- class cardinal_pythonlib.enumlike.AutoStrEnumMeta(cls, bases, oldclassdict)[source]
Scan through
oldclassdict
and convert any value that is a plain tuple into astr
of the name instead.
- class cardinal_pythonlib.enumlike.AutoStringObject
Usage:
class Fish(AutoStringObject): Thing Blah Fish.Thing # 'Thing'
- class cardinal_pythonlib.enumlike.CaseInsensitiveEnumMeta(cls, bases, classdict)[source]
An Enum that permits lookup by a lower-case version of its keys.
https://stackoverflow.com/questions/42658609/how-to-construct-a-case-insensitive-enum
Example:
from enum import Enum from cardinal_pythonlib.enumlike import CaseInsensitiveEnumMeta class TestEnum(Enum, metaclass=CaseInsensitiveEnumMeta): REDAPPLE = 1 greenapple = 2 PineApple = 3 TestEnum["REDAPPLE"] # <TestEnum.REDAPPLE: 1> TestEnum["redapple"] # <TestEnum.REDAPPLE: 1> TestEnum["greenapple"] # <TestEnum.greenapple: 2> TestEnum["greenappLE"] # <TestEnum.greenapple: 2> TestEnum["PineApple"] # <TestEnum.PineApple: 3> TestEnum["PineApplE"] # <TestEnum.PineApple: 3>
- class cardinal_pythonlib.enumlike.EnumDict[source]
A copy of enum._EnumDict from Python 3.6 that we are allowed to access and doesn’t vanish in Python 3.9.
Track enum member order and ensure member names are not reused.
EnumMeta will use the names found in self._member_names as the enumeration member names.
- class cardinal_pythonlib.enumlike.LowerCaseAutoStrEnum(value)[source]
Base class for
name=value
str
enums, forcing lower-case values.Example:
class AnimalLC(LowerCaseAutoStrEnum): Horse = () Dog = () Whale = () print(AnimalLC.Horse) print(AnimalLC.Horse == 'horse') print(AnimalLC.Horse.name, AnimalLC.Horse.value)
- class cardinal_pythonlib.enumlike.LowerCaseAutoStrEnumMeta(cls, bases, oldclassdict)[source]
Scan through
oldclassdict
and convert any value that is a plain tuple into astr
of the name instead.
- class cardinal_pythonlib.enumlike.LowerCaseAutoStringObject
Usage:
class Wacky(LowerCaseAutoStringObject): Thing # or can use Thing = () to avoid IDE complaints OtherThing = () Wacky.Thing # 'thing' Wacky.OtherThing # 'otherthing'
- class cardinal_pythonlib.enumlike.OrderedNamespace(*args)[source]
As per https://stackoverflow.com/questions/455059, modified for
__init__
.
- class cardinal_pythonlib.enumlike.StrEnum(value)[source]
StrEnum:
makes
str(myenum.x)
givestr(myenum.x.value)
adds a lookup function (from a string literal)
adds ordering by value
- cardinal_pythonlib.enumlike.keys_descriptions_from_enum(enum: Type[Enum], sort_keys: bool = False, keys_to_lower: bool = False, keys_to_upper: bool = False, key_to_description: str = ': ', joiner: str = ' // ') Tuple[List[str], str] [source]
From an Enum subclass, return (keys, descriptions_as_formatted_string). This is a convenience function used to provide command-line help for options involving a choice of enums from an Enum class.