Enum可以用作调度表吗?

时间:2017-04-17 09:13:55

标签: python enums

this blog post的第一部分很好地总结了调度表的一般用例,但我无法想知道它是否可以使用{{1}更加简洁和优雅而不是......

当然,使用Enum的一大障碍是函数会被自动忽略为潜在成员。

那么,有可能吗?

2 个答案:

答案 0 :(得分:1)

总之: 1

我将使用the aenum2 library显示解决方案 - 虽然可以使用stdlib版本执行大部分操作,但需要编写Enum中已存在的额外管道。

首先,基类:

aenum

和示例调度from aenum import Enum, enum class CallableEnum(Enum): def __new__(cls, *args, **kwds): member = object.__new__(cls) member._impl = args[0] if member._impl.__doc__ is not None: member._value_ = member._impl.__doc__ else: member._value_ = repr(member._impl) return member def __call__(self, *args, **kwds): return self._impl(*args, **kwds)

Enum

并在使用中:

class TestEnum(CallableEnum):

    @enum
    def hello(text):
        "a pleasant greeting"
        print('hello,', text)

    @enum
    def goodbye(text):
        print('goodbye,', text) 

1 有关标准>>> list(TestEnum) [ <TestEnum.hello: 'a pleasant greeting'>, <TestEnum.goodbye: '<function goodbye at 0xb7264844>'>, ] >>> print(TestEnum.hello) TestEnum.hello >>> TestEnum['hello']('how are you?') 'hello, how are you?' >>> TestEnum['goodbye']('see you soon!') 'goodbye, see you soon!' 的使用,请参阅this answer

2 披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum)图书馆的作者。

答案 1 :(得分:0)

所以首先我使用了上面的实现,但是后来意识到它在OSX上不能正确地进行酸洗,所以现在我在使用它:

    def _utcnow_plus_delta(delta: timedelta, utcnow_attr: tOptional[str] = None, delta_attr: tOptional[str] = None):
        dt = datetime.utcnow()
        if utcnow_attr:
            dt = getattr(dt, utcnow_attr)
            if callable(dt):
                dt = dt()

        dt += delta

        if delta_attr:
            delta_val = getattr(dt, delta_attr)
            return delta_val() if callable(delta_val) else delta_val

        return dt


    @unique
    class DynamicValue(Enum):
        DATE_TODAY_PLUS_ONE_DAY = partial(_utcnow_plus_delta, timedelta(days=1), 'date')
        DATE_TODAY_PLUS_TWO_YEARS = partial(_utcnow_plus_delta, timedelta(weeks=52 * 2), 'date')
        DATE_TODAY_PLUS_FIVE_YEARS = partial(_utcnow_plus_delta, timedelta(weeks=52 * 5), 'date')
        DATE_TODAY_PLUS_TEN_YEARS = partial(_utcnow_plus_delta, timedelta(weeks=52 * 10), 'date')
        YEAR_TODAY_PLUS_FIVE_YEARS = partial(_utcnow_plus_delta, timedelta(weeks=52 * 5), 'date', delta_attr='year')
        TIMESTAMP_NOW_PLUS_FIVE_YEARS = partial(_utcnow_plus_delta, timedelta(weeks=52 * 5), delta_attr='timestamp')

        def __reduce_ex__(self, proto):
            assert proto >= 4
            return self.__class__.__qualname__ + '.' + self._name_

我认为上述CallableEnum可以通过添加适当的reduce_ex方法来解决,以确保从全局值而不是repr重新创建它。有点烦人,因为您必须执行enum.value(),但我认为并没有太大意义