如何输入hint参数,使其值必须是类的属性?

问题描述 投票:0回答:1

我正在使用以下类(它来自 Airflow 代码,所以我无法修改它):

class TriggerRule:
    """Class with task's trigger rules."""

    ALL_SUCCESS = 'all_success'
    ALL_FAILED = 'all_failed'
    ALL_DONE = 'all_done'
    ONE_SUCCESS = 'one_success'
    ONE_FAILED = 'one_failed'
    NONE_FAILED = 'none_failed'
    NONE_FAILED_OR_SKIPPED = 'none_failed_or_skipped'
    NONE_SKIPPED = 'none_skipped'
    DUMMY = 'dummy'

    _ALL_TRIGGER_RULES: Set[str] = set()

    @classmethod
    def is_valid(cls, trigger_rule):
        """Validates a trigger rule."""
        return trigger_rule in cls.all_triggers()

    @classmethod
    def all_triggers(cls):
        """Returns all trigger rules."""
        if not cls._ALL_TRIGGER_RULES:
            cls._ALL_TRIGGER_RULES = {
                getattr(cls, attr)
                for attr in dir(cls)
                if not attr.startswith("_") and not callable(getattr(cls, attr))
            }
        return cls._ALL_TRIGGER_RULES

假设我有这个功能:

def print_rule(rule):
    print(rule)

并且我想输入提示参数

rule
所以它必须是
TriggerRule
类中列出的规则之一。

print_color(TriggerRule.ALL_FAILED)  # OK
print_color('one_success')  # I don't care if it complains or not
print_color('foo')  # I want it to complain

这可能吗?我不想将其输入为

str
,因为我不想允许任何字符串。

我使用的是 Python 3.8,但如果在较新的版本中可以这样做,我也想知道。

python python-typing
1个回答
0
投票

您始终可以使用

TYPE_CHECKING
对类型检查器撒谎,在类型检查时为
True
,但在运行时为
False

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from enum import Enum

    class TriggerRule(str, Enum):  # Or StrEnum in 3.11+
        ALL_SUCCESS = 'all_success'
        ALL_FAILED = 'all_failed'
        # Other rules here...

        @classmethod
        def is_valid(cls, trigger_rule: str) -> bool: ...

        @classmethod
        def all_triggers(cls) -> set[str]: ...
            
else:
    from external_package import TriggerRule

然后像真实的一样使用它

Enum
:

def print_rule(rule: TriggerRule) -> None:
    print(rule)

结果将是:

print_color(TriggerRule.ALL_FAILED)  # fine
print_color('one_success')           # error: 'one_success' is not a TriggerRule
print_color('foo')                   # error: 'foo' is not a TriggerRule
© www.soinside.com 2019 - 2024. All rights reserved.