首页 > 解决方案 > 为了在python中调用隐藏的类方法,有什么干净的替代方法?

问题描述

我有两个具有一些共享结构的项目,但项目的具体要求不同。为了解决这个问题,我创建了两个基类:

class AbstractBaseClassA:
    def __init__(self) -> None:
        # do something
        pass


class AbstractBaseClassB:
    def __init__(self, a: AbstractBaseClassA) -> None:
        self.a = a
        # do something

我有几个抽象方法,做一些项目之间共享的工作,但现在想进入项目细节。因此,我创建了另外两个类:

class ProjectSpecificClassA(AbstractBaseClassA):
    def __init__(self) -> None:
        super().__init__()
        # do something

    def someOtherMethod(self) -> None:
        # do something
        pass


class ProjectSpecificClassB(AbstractBaseClassB):
    def __init__(self, a: ProjectSpecificClassA) -> None:
        super().__init__(a)
        # do something
        self.a.someOtherMethod()  # <-- unresolved attribute reference

现在,在最后一行ProjectSpecificClassB,我想调用一个项目特定的函数ProjectSpecificClassA,但是由于继承AbstractBaseClassB,这个方法是未知的。在像 Java 这样的语言中,这就是我要转换为的点self.aProjectSpecificClassA但由于 python 不支持转换,我正在寻找一种替代方法。我知道,从技术上讲,上述解决方案有效,但我想知道是否有一个更干净的解决方案也被 linter / 预编译器承认?

标签: pythonpython-3.xinheritancecastingtype-safety

解决方案


Python 是动态的。这意味着someOtherMethod将在运行时搜索,并且将被找到,因为a它实际上是一个ProjectSpecificClassA对象。

在 Java 中需要强制转换,就像在 C++ 中一样,因为方法是在编译时搜索的,因此编译器必须知道在哪里找到它。

Python 比这更宽容。如果您不使用特殊处理(例如__slots__阻止动态属性创建),则可以将方法添加到特定对象并使用它。你可以这样使用你的类:

a = ProjectSpecificClassA()
b = ProjectSpecificClassB(a)
b.a.special = lambda x: 2 * x
ProjectSpecificClassB.special = lambda self: self.a.special(3)

assert (b.special() == 6)

推荐阅读