Pylance reportUnknownMemberType 即使变量类型已知

Pylance reportUnknownMemberType even though variable type is known

我在 VSCode 上使用 Pylance,我得到这个 reportUnknownMemberType warning/error 这个变量,尽管我可以看到它知道类型。

我是 classes 的新手,所以如果有更好的方法,请告诉我。我的目标是用子 class 中的更多键扩展父 class 字典。该程序实际上正在运行,父字典获得了新的键值对,但我想知道为什么我会收到 Pylance 错误。

以下是这些class类的继承链,名称简化但结构真实。涉及 3 个 classes,像 Base > SubClass > SubSubClass 一样继承。 Base class 在单独的文件中找到:

#base.py
     
class Base:
    def __init__(self, param0: str) -> None:
        self.param0 = param0
        self.exportable = dict[str, object]()        
 

另外 2 个 classes 在第二个文件中找到:

# subclasses.py

class SubClass(Base):
    def __init__(self, param0: str, param1: str, param2: str, 
                     param3: str, param4: str, 
                     param5: bool=True) -> None:
        super().__init__(param0)
    
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3
        self.param4 = param4
        self.param5 = param5

        self.exportable = {
            self.param0: {
                'param1': self.param1,
                'param2': self.param2,
                'param3': self.param3,            
                'param4': self.param4,
                'param5': self.param5
            }
        }


class SubSubClass(SubClass):
    def __init__(self, param1: str, param3: str) -> None:        
        super().__init__(name='hardcodedparam0', param1=param1, type='hardcodedparam2', param3=param3, 
                param4='hardcodedparam4')

    self.properties = {
        'name': {
            'type': "string"
        },
        'contentBytes': {
            'type': 'string',
            'format': 'byte'
        }
    }

    # this is where I get the error
    new_exportable = self.exportable.copy()
    self.exportable = {**new_exportable, **self.properties}

我最初的计划是只使用 self.exportable[self.name]['properties'] = self.properties 而不是那个字典合并,但我得到了这个 cannot assign 错误。

我也尝试在 SubSubClass 中使用 super().exportable 访问子类的 self.exportable,虽然我认为这不是必需的,但是当我 运行 程序时,我得到一个错误说 super() has no attribute 'exportable'。对于它的价值,这个 super() 尝试在没有 运行 程序时也会从上面给出相同的 'cannot assign' 错误。

使用第一个选项(dict 合并)和第二个选项(分配新的属性键和值),程序运行并且 self.properties dict 成功附加到继承的 self.exportable字典。但我想知道我是否做错了什么,或者 Pylance 是否只是感到困惑。我认为它很困惑,因为在子类中它看到字典只是 dict[str,Union[str,bool]] 但是子类 B 而不是 Union[str,bool] 值,试图添加 properties 字典,这是一组字典的本身?

当然,我可以让 Pylance 配置中的 reportUnkownMemberType 错误静音,但我担心我掩盖了一些我不知道的东西。

谢谢

我想我可能已经通过更灵活地使用 SubClass 的可导出来解决了这个问题。也就是说,创建一个空字典,添加初始属性,并在 SubSubClass 中添加任何添加项:

# subclasses.py

class SubClass(Base):
    def __init__(self, param0: str, param1: str, param2: str, 
                     param3: str, param4: str, 
                     param5: bool=True) -> None:
        super().__init__(param0)
    
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3
        self.param4 = param4
        self.param5 = param5

        # The following two lines are a bit different
        self.exportable = {}
        self.exportable[self.param0] = {
            'param1': self.param1,
            'param2': self.param2,
            'param3': self.param3,            
            'param4': self.param4,
            'param5': self.param5
        }
 


class SubSubClass(SubClass):
    def __init__(self, param1: str, param3: str) -> None:        
        super().__init__(name='hardcodedparam0', param1=param1, type='hardcodedparam2', param3=param3, 
                param4='hardcodedparam4')
        self.properties = {
            'name': {
                'type': "string"
            },
            'contentBytes': {
                'type': 'string',
                'format': 'byte'
            }
        }

        # Now I can assign a key and value with no Pylance error
        self.exportable[self.name]['properties'] = self.properties

区别似乎介于

  • 将初始可导出字典设置为具有固定键 (param0) 和值(param1param2param3 等的子字典)
  • 将初始可导出项设置为空字典,分配 param0 键和值,然后在 SubSubClass 中分配一个新的键值

我不确定这是否只是一种变通方法,我是否只是设法欺骗 Pylance 使其不再抱怨,或者这是否是实际的解决方案。无论如何,我不再收到 Pylance 错误并且程序(仍然)有效。