Python 将API更改为许多实用程序类

Python 将API更改为许多实用程序类,python,Python,我有很多课程,为不同的站点实现一些常规任务: class AbstractCalculator : pass # ... abstract methods lying here class Realization1 (AbstractCalculator) : @classmethod def calculate_foo(...) : # ... @classmethod def calculate_bar(...) :

我有很多课程,为不同的站点实现一些常规任务:

class AbstractCalculator :
         pass # ... abstract methods lying here

class Realization1 (AbstractCalculator) :

    @classmethod
    def calculate_foo(...) :
        # ...

    @classmethod
    def calculate_bar(...) :
        # ...



class Realization2 (AbstractCalculator) :

    @classmethod
    def calculate_foo(...) :
        # ...

    @classmethod
    def calculate_bar(...) :
        # ...
然后我将所有这些类聚合到一个字典中 现在我介绍新的不同API:

class NewAbstractClass :

    # ... introducting new API ...

    @staticmethod
    def adopt(old_class) :
         # .. converting AbstractClass to NewAbstactClass
然后我使用类似@decorator的adopt()方法将所有旧的实现转换为新的

但这一切都非常奇怪和复杂。有没有更好的办法

UPD@ColinMcGrath:

不,我问的肯定是别的

我的adopt()修饰符正在工作,我对它的功能没有任何问题(只是,它的主体与我的问题无关,所以我没有提供它)


我认为,在源代码中对几十个不同的网络类进行硬编码修饰并不是一个好主意,而是在寻找规范的解决方案。

一般来说,代码没有神奇的方式知道一个api等同于另一个api

然而,python中用于类的过程生成的机制是元类和类装饰器。您可以使用一个元类,它使用您提供给它的一些信息来生成另一个类。 这是一个很好的介绍:

由于python的“鸭式类型”,抽象类很少是必需的,而且有点代码味道。您可能应该重新设计代码,这样就不需要重命名和抽象类了。特别是,如果您的代码需要更改,它需要更改。如果您正在包装外部代码以使几个不同的API兼容,我只会这样做

比如:

class renamer(type):
     def __init__(cls, classname, bases, dct):
         if '__rename__' in dct:
            dct.update(cls.__rename__)

class orig(object):
      def foo(*params): pass

class newclass:
      __meta__ = renamer
      __rename__ = (('bar', orig.foo),)
或者,你也可以对装饰师做类似的事情:

def renamer(subs):
    def thedecorator(inclass):
        meta = type(inclass)
        dct = inclass.__dict__.copy()
        dct.update(subs)
        return meta(inclass.__name__,inclass.__bases__,dct)
   return thedecorator

@renamer((('bar', orig.foo),))
class newclass(object): pass

您是在寻找手动解决方案还是自动执行此操作的库?@ColinMcGrath我正在寻找通用设计模式。我知道我产生了一些非常难看的东西,正在寻找最好的方法。@ColinMcGrath例如,我知道ZCA的适配器可以做到这一点,但我觉得可以用更方便的方式解决它。我发现另一个堆栈溢出问题处理类似的问题。这能解决你的问题吗?“我认为在源代码中对几十个不同的类进行硬编码装饰并不是一个好主意”-为什么让类的源代码a)反映实际的API,b)明确地说明发生了什么是一个坏主意?