【问题标题】:Incompatible types in assignment on Union联合分配中的不兼容类型
【发布时间】:2018-01-06 13:06:59
【问题描述】:

Mypy 向我打印以下消息:

x.py:74: 错误:赋值中的类型不兼容(表达式有类型 "Union[str, Dict[str, str]]", 变量类型为"str")

这不奇怪吗? strUnion[str, Dict[str, str]] 的一部分

代码如下:

def get_multiple(fields: List[str], config_data) -> Dict[str, str]:
    config_results = {k: v for k, v in config_data.items() if k in fields}
    log_missing_fields(fields, config_results)
    return config_results


def get_single(field: List[str], config_data) -> str:
    result = config_data.get(field)
    if result is None:
        log.warning('The following fields are missing: %s', field)
    return result


def get(fields: Union[str, List[str]]) -> Union[str, Dict[str, str]]:
    log.debug('Retrieving values %s from config', str(fields))
    config_data = read_config()
    get_data = get_multiple if isinstance(fields, list) else get_single
    return get_data(fields, config_data)


def get_ts_url() -> str:
    timeout = get('timeout')  # type: str <-- Line 74 is here
    log.info('Trying to connect the servers.')
    with db_session() as db_handler:
        url = scan_availability(db_handler, int(timeout))

    if url:
        return url

    log.critical("Could not find available servers.")
    raise ConnectionError("Could not find available servers.")

【问题讨论】:

  • 问题是Union[str, Dict[str, str]] 不是str 的一部分。
  • 换句话说,您试图将可以是strdict 的东西分配给只能包含str 的变量。如果get() 返回字典怎么办?

标签: python python-3.x types python-3.5 mypy


【解决方案1】:

避免此问题的正确方法是使用@overload 装饰器来描述函数参数与其结果之间的关系。

函数get() 将返回一个str(实际上是一个Optional[str],因为它也可能返回None)如果它被传递一个str,它会返回一个字典如果它被传递一个@987654327 @。以下是我们使用类型注释来描述它的方式:

from typing import *


def read_config() -> Dict[str, str]:
    return {}


def get_multiple(fields: List[str], config_data: Dict[str, str]) -> Dict[str, str]:
    config_results = {k: v for k, v in config_data.items() if k in fields}
    return config_results


def get_single(field: List[str], config_data: Dict[str, str]) -> Optional[str]:
    result = config_data.get(field)
    return result


@overload
def get(fields: str) -> Optional[str]: ...

@overload
def get(fields: List[str]) -> Dict[str, str]: ...

def get(fields):
    config_data = read_config()
    get_data = get_multiple if isinstance(fields, list) else get_single
    return get_data(fields, config_data)


def get_ts_url() -> None:
    timeout = get('timeout')
    if TYPE_CHECKING:
        reveal_type(timeout)

如果你在上面运行 mypy,它会打印出来

Revealed type is 'Union[builtins.str, builtins.None]'

我还建议将来在发布之前花几分钟时间来简化您的示例,以便其他人可以重现它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    相关资源
    最近更新 更多