python 如何自动将未实现的方法委托给不同的类?

abithluo  于 2023-05-21  发布在  Python
关注(0)|答案(1)|浏览(134)

我有一个class A,它实现了方法x()y(),但我也有一个class B,它实现了方法z()。假设有一个AbstractA基类。如何检测class A上未实现的任何调用,例如z()并转发给class B?请注意,由于框架问题,我不能让AB继承,即,

from abc import ABC, abstractmethod   

class AbstractA(ABC):
   # some magic for catching unimplemented method calls e.g. z
   # and forward them to B's. Here I have access to instances of
   # B e.g. context.b.z()
   
   @abstractmethod
   def x():
     pass

   @abstractmethod
   def y():
     pass

class A(AbstractA):
  def __init__(self):
    super().__init__()

  def x():
    print('running x()')

  def y():
    print('running y()')

class B:
  def __init__(some plumbing args):
     super().__init__(some plumbing args) 

  def z():
     print('running z()')
 
a = A()
a.x()
a.y()
a.z()

为了给这个用例给予一点上下文,我有一个多层体系结构,其中有一个数据访问层(DAL),然后是一个服务应用层(SAL)。DAL是负责 Package 所有数据库访问用例的DAO的集合。SAL构建在DAL之上,并混搭了DAL的数据和业务应用程序逻辑。
例如,PersonDao实现和PersonService实现。PersonService将调用PersonDao来构建业务逻辑API,但有时客户端代码可能会请求PersonService通过id查找人,这在PersonDao中直接实现。因此,与其为每个DAO方法显式地实现一个直通服务方法,不如在PersonService的抽象基础级别上自动化这个直通或委托,这样如果您执行person_service.find_by_id(3),它将直接转到PersonDao#find_by_id(id),从而有效地使服务实现成为底层DAO的门面。

jgovgodb

jgovgodb1#

from abc import ABC, abstractmethod
from inspect import isfunction

class AbstractA(ABC):
    # some magic for catching unimplemented method calls e.g. z
    # and forward them to B's. Here I have access to instances of
    # B e.g. context.b.z()

    @abstractmethod
    def x(self):
        pass
    @abstractmethod
    def y(self):
        pass

class A(AbstractA):
    def __init__(self):
        super().__init__()
        self.checker = 'value in A'

    def x(self):
        print('running x()')

    def y(self):
        print('running y()')

class B:
    def __init__(self, some_plumbing_args = None):
        self.checker = 'value in B'
    
    def z(self):
        print('running z()')
        print(self.checker)

仅在class B中获取函数名。将函数绑定到class A

functions_name_of_A = set(name for name, obj in A.__dict__.items() if isfunction(obj) == True and not name.startswith('__'))
functions_name_of_B = set(name for name, obj in B.__dict__.items() if isfunction(obj) == True and not name.startswith('__'))
functions_name = functions_name_of_B - functions_name_of_A

for name in functions_name:
    setattr(A, name, B.__dict__[name])

class A中的值由z()显示。

a = A()
a.x()
a.y()
a.z()
>>> running x()
>>> running y()
>>> running z()
>>> value in A

仅在class B中的值也由z()显示。

b = B()
b.z()
>>> running z()
>>> value in B

相关问题