【问题标题】:pycharm type checker expected type dict, got 'None' insteadpycharm 类型检查器预期类型 dict,改为“无”
【发布时间】:2017-12-26 09:58:02
【问题描述】:

在这个sn-p中:

from typing import Dict, Optional 
class T:
    def __init__(self):
        self.bla = {}

    def t(self) -> Dict:
        if self.bla is None:
            self.bla = {'not none': 'nope!'}
        return self.bla

谁能解释一下为什么intellij/pycharm的类型检查器认为这个方法的返回值是None

如果我将t()的返回类型注释为Optional[Dict],类型检查器似乎才满意,但是这种方法永远不会返回None,所以我认为它不应该是可选的。

如果我将__init__() 中的self.bla 的初始值更改为{},返回值仍然是None。如果我使用str 而不是dict,则会出现同样的错误

【问题讨论】:

  • 可能是因为if self.bla is None签入你的代码。
  • if self.bla: 后面紧跟self.bla = ____,没有代码路径可以离开它None
  • 伙计,python 是一种动态类型的语言。例如,您可以覆盖 __setattr__ 属性,以便 self.bla 将您的 bla 设置为 None。我认为pycharm的行为是一致的。
  • 如果是这样,那么为什么类型检查器会如此确定self.blaNone?我知道 python 是动态的,你可以深入 cloud-coo-coo-land,但类型检查器只能处理它看到的内容。考虑到这一点,你能说出为什么None 的测试让它认为价值仍然是None,而当它明显改变为不是的东西时?
  • 更多的是类型检查器不能确定它我 not None,遇到这个问题是为了解决它可以是 None 的问题,所以我使用了 Optional[dict]

标签: python pycharm typechecking


【解决方案1】:

使用以下 -> Dict or None 注释 pycharm (2019.2) 不会抱怨,我得到 dict 类型自动补全 fdictnoneres

def fdictnone() -> Dict or None:
    return dict(a=1, b=2)


fdictnoneres = fdictnone()

当使用TypeVar 时,pycharm 不为tfunres 提供dict 类型自动补全:

from typing import TypeVar


T = TypeVar('T', dict, None)


def tfun() -> T:
    return dict(a=1, b=2)


tfunres = tfun()

【讨论】:

  • 对于拥有足够新版本 pycharm 的人来说,您的解决方案绝对是最有效的
  • Dict or None,难道你不能做'或'的事情!很高兴知道
  • 我不知道为什么当一个变量可以有 None 值直到正确的值被分配给它时,为什么 None 会被区别对待。
  • PyCharm 2020.3.2 不会为我自动完成“列表或无”:( 截图 - i.ibb.co/wRqbZnc/2021-02-04-17-01-38.png
【解决方案2】:

可以做但不应该做的事情是这样的:

class T:
    def __init__(self):
        self.bla = {}

    def t(self) -> dict:
        if self.bla is None:
            result = {'not none': 'nope!'}
            self.bla = result
            return result
        else:
            return self.bla

这样,变量被单独识别。但是请注意,这个解决方案是愚蠢的——你只是在为我认为 PyCharm 中的一个错误做一个解决方法!其实我也有同样的问题,还是没有解决办法……

现在我建议要么忽略警告,要么通过添加强制 PyCharm 忽略它:

# noinspection PyTypeChecker

我在某处读到过,类型提示尚未在 PyCharm 中完全实现,所以可能还会出现……不过我不记得我在哪里读到的,所以不能保证!

【讨论】:

  • 这个“不应该做”正是我正在做的让它类型检查:) 但我同意。
【解决方案3】:

我发现类型提示实例变量有效。我似乎也没有在 2018 专业版 pycharm 中出现原始检查错误,所以我想知道他们是否已将检查更新为更智能一些。

class T(object):
    def __init__(self):
        self.bla:Dict = None

    def t(self) -> Dict:
        if self.bla is None:
            self.bla = {'foo' : 'bar'}
        return self.bla

【讨论】:

  • self.bla: Dict = None 在 PyCharm 2021.2.1(社区版)中给了我Expected type 'dict', got 'None' instead。 :(
【解决方案4】:

我很确定这是因为它在您的构造函数中被初始化为 None 。 我相信如果您在类定义中明确说明类型,它应该可以工作。例如:

class T:
    bla: Dict

    def __init__(self):
        self.bla = None

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 2018-09-23
    • 2014-07-20
    • 2021-07-14
    • 2021-06-11
    • 1970-01-01
    • 2020-02-09
    • 2020-07-21
    • 2021-02-28
    相关资源
    最近更新 更多