链接子类层次结构中的方法以执行以获得层次结构中所有方法执行的并集

时间:2018-08-22 11:09:34

标签: python python-3.x inheritance decorator

让我们考虑一下我的要求的简化版本

class Base:
    def __method(self):
        self.base = 'my-base'


class SubClass(Base):
    def __method(self):
        self.sub = 'my-sub'

我希望我的SubClass实例同时包含 base sub

让我们考虑一下我在实际需求中的尝试

from configargparse import ArgParser


class BaseConf(object):
    def __init__(self) -> None:
        super().__init__()
        self._parser = ArgParser()
        self.__add_arg()

    def pop(self, args):
        first_base = self.__class__.__bases__[0]
        if first_base is not object:
            super().__populate_arg(args) # <----------Compile failure------->
        self.__populate_arg(args)

    def __add_arg(self):
        self._parser.add_argument('--base', type=str, default='NA')

    def __populate_arg(self, args):
        self.base = args.base


class SubConf(BaseConf):

    def __init__(self) -> None:
        super().__init__()
        self.__add_arg()

    def __add_arg(self):
        self._parser.add_argument('--sub', type=str, default='NA')

    def __populate_arg(self, args):
        self.sub = args.sub


conf = SubConf()
args, _ = conf._parser.parse_known_args()
conf.pop(args)
assert all(x in conf.__dict__ for x in ['base', 'sub'])

最终,我希望断言条件通过。我已经提到了通过标记编译失败引起麻烦的代码行。

我还将考虑全面改进方法并尝试更好的方法。

感谢您的时间。

1 个答案:

答案 0 :(得分:2)

正如我在评论中说的那样,使用名称混乱的__private方法的全部目的是确保属性/方法是私有的-它们仅被该类限制使用-不是它的子类。您可以通过删除开头的下划线,使用方法_protectedpublic来轻松解决此问题。例如:

class Base:
    def method(self):
        self.base = 'my-base'

class SubClass(Base):
    def method(self):
        self.sub = 'my-sub'
        super().method()

这是非常不建议的,但是如果您绝对必须从基类中获取私有属性,则可以使用

class Base:
    def __method(self):
        self.base = 'my-base'

class SubClass(Base):
    def method(self):
        self.sub = 'my-sub'
        super()._Base__method()

,但这仅在您知道超类的名称时才有效。如果不是的话,您就必须变得很hacky,例如

 class SubClass(Base):
    def method(self):
        self.sub = 'my-sub'
        sup = self.__class__.mro()[1].__name__
        getattr(super(), f'_{sup}__meth')()