首页 > 解决方案 > 打字:如何考虑用部分包装的类参数?

问题描述

我有一个 MyClass 类,它需要一个类 parent_cls 作为填充接口 ParentInterface 的参数。

ChildA 从 ParentInterface 实现/扩展。由于在 MyClass 内部,parent_cls 使用参数 a 和 b 实例化,因此 ChildA 的附加参数 c 部分在外部实例化。

原则上,这确实在 Python 中运行。但是我从 Pycharm 收到类型警告: 在此处输入图像描述

任何想法如何解决该类型警告?

from abc import ABC, abstractmethod
from functools import partial
from typing import Type, Optional, Callable, cast


class ParentInterface(ABC):
    def __init__(self, a: int, b: int):
        self.a = a
        self.b = b

    @abstractmethod
    def do_something(self):
        pass


class ChildA(ParentInterface):
    def __init__(self, a: int, b: int, c: str):
        super().__init__(a, b)
        self.c = c

    def do_something(self):
        print('I am ChildA')


# update 1
class ChildB(ParentInterface):
    def __init__(self, a: int, b: int):
        super().__init__(a, b)

    def do_something(self):
        print('I am ChildB')


class MyClass:
    def __init__(self, parent_cls: Type[ParentInterface]):
        self.parent = parent_cls(3, 4)

# alternative
# class MyClass:
#     def __init__(self, parent_cls: Callable[[int, int], ParentInterface]):
#         self.parent = parent_cls(3, 4)


def typed_partial(cls, *args, **kwargs):
    return cast(Type[cls], partial(cls, *args, **kwargs))

# original code
# child_a_cls = partial(ChildA, c='some string')
# solution
child_a_cls = typed_partial(ChildA, c='some string')

my_class_with_childa = MyClass(parent_cls=child_a_cls)
my_class_with_childb = MyClass(parent_cls=ChildB)

更新:添加了来自@a_guest 的解决方案以及@user2357112 提出的使用 Callable[[int, int], ParentInterface] 的替代 Typing 支持 Monica。

标签: pythonpython-3.x

解决方案


您可以指定parent_cls变量的类型,例如partial[ParentInterface]

from typing import Optional

class MyClass:
    def __init__(self, parent_cls: Optional[partial[ParentInterface], ParentInterface]):
        self.parent = parent_cls(3,4)

你必须记住functools.partial是一个类


推荐阅读