0

我有一个 Python 系统,由大约 9-10 个类组成,所有类都实现了大部分胖鸭式接口,并且可以被大量模块互换使用。我正在尝试将类重构为核心、显式(即 ABC)接口和外围功能,遵循职责分离,但为了做到这一点,我需要能够判断消费者模块何时调用核心之外的方法界面。

假设我有一个带有抽象方法的 ABC:

from abc import ABCMeta, abstractmethod

class MyABC:
    __metaclass__ = ABCMeta
    @abstractmethod 
    def foo(self):
        pass

我还有一个实现这些抽象方法以及其他方法的类:

class MyClass(MyABC):
    def foo(self):
        pass
    def bar(self):
        pass

instance = MyClass()

>>> isinstance(instance, MyABC)
True

我如何确保当我传递instance给一个方法do_something时,它只使用属于MyABC(在这种情况下foo)的方法而不是任何其他方法(bar)?在静态类型语言(例如 C++)中,我可以传递do_somethingABC 类型的指针;Python中是否有某种包装器可以类似地限制方法访问?

4

2 回答 2

0

简短的回答:没有

Python 中没有可以强制执行的私有方法/变量的概念,如此处详细描述

在 Python 中,这是按惯例处理

如果您真的想深入了解内部结构,请查看此线程

于 2012-08-23T09:01:01.833 回答
0

这就是我想出的:

class ABCGuard(object):
    def __init__(self, obj, *abcs):
        if any(not isinstance(obj, abc) for abc in abcs):
            raise ValueError("{0} must implement {1}"
                             .format(obj.__class__.__name__,
                                     ', '.join(abc.__name__ for abc in abcs
                                               if not isinstance(obj, abc))))
        self.__obj = obj
        self.__abcs = abcs
        classname = '{0}{{{1}}}'.format(obj.__class__.__name__,
                                        ', '.join(abc.__name__ for abc in abcs))
        self.__class__ = type(classname, (ABCGuard, ) + abcs, {})

    def __getattribute__(self, name):
        if name.startswith('_ABCGuard__') or (name.startswith('__') and
                                              name.endswith('__')):
            return super(ABCGuard, self).__getattribute__(name)
        elif any(name in abc.__abstractmethods__ for abc in self.__abcs):
            return getattr(self.__obj, name)
        else:
            raise AttributeError("%r object has no attribute %r" %
                                 (self.__class__.__name__, name))

    def __dir__(self):
        return [x for abc in self.__abcs for x in abc.__abstractmethods__]
于 2012-08-30T10:09:23.130 回答