我有一个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
的方法(在这种情况下{ {1}})而不是任何其他方法(foo
)?在静态类型语言(例如C ++)中,我可以传递bar
ABC类型的指针; Python中是否有某种类型的包装器可以同样限制方法访问?
答案 0 :(得分:0)
答案 1 :(得分: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__]