PyCharm 给我类型警告; mypy 不同意

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

我正在尝试编写一个名为

Singleton
的元类,当然,它实现了单例设计模式:

class Singleton(type):
    
  def __new__(cls, name, bases = None, attrs = None):
    if bases is None:
      bases = ()
        
    if attrs is None:
      attrs = {}
        
    new_class = type.__new__(cls, name, bases, attrs)
    new_class._instance = None
    return new_class
    
  def __call__(cls, *args, **kwargs):
    if cls._instance is None:
      cls._instance = cls.__new__(cls, *args, **kwargs)
      cls.__init__(cls._instance, *args, **kwargs)
        
    return cls._instance

这似乎工作正常:

class Foo(metaclass = Singleton):
  pass

foo1 = Foo()
foo2 = Foo()

print(foo1 is foo2)  # True

但是,PyCharm 给了我这个警告

cls._instance = cls.__new__(cls, *args, **kwargs)

Expected type 'Type[Singleton]', got 'Singleton' instead

...这是

cls.__init__(cls._instance, *args, **kwargs)

Expected type 'str', got 'Singleton' instead

我在同一个文件上运行 mypy,它是这样说的:

# mypy test.py
Success: no issues found in 1 source file

我使用的是 Python 3.11、PyCharm 2023.1.1 和 mypy 1.3.0,如果有区别的话。

那么这里到底有什么问题呢?我这样做正确吗?这是 PyCharm、mypy 或其他东西的错误吗?如果错误在我身上,我该如何解决?

python pycharm type-hinting mypy metaclass
1个回答
0
投票

既然你也在问“我这样做对吗?”,你为什么不使用这样一个更简单的解决方案:

class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]


class Foo(metaclass=SingletonMeta):
    ...


foo1 = Foo()
foo2 = Foo()

print(foo1 is foo2)  # still True

这样可以避免构造造成混淆和警告。我很感激我没有回答为什么 PyCharm 正在检测您认为不正确的类型冲突的问题——它们可能是,我没有深入挖掘以弄清楚为什么 PyCharm 会这么想。

如果你只是想摆脱警告,在你确定问题没有被正确识别之后:

    # noinspection PyTypeChecker
    cls._instance = cls.__new__(cls, *args, **kwargs)

如果您发现到底出了什么问题,您应该向 JetBrains 提交错误报告(并在您的#noinspection 中添加一个#todo 以提醒您自己在修复后将其删除)。

© www.soinside.com 2019 - 2024. All rights reserved.