5

我有很多课程,实现了不同站点的一些一般任务:

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 这样的采用()方法,将所有旧实现转换为新实现。

但这一切都非常奇怪和复杂。有没有更好的方法来做到这一点?

UPD @ColinMcGrath:

不,我肯定在问其他人。

我的采用()装饰器正在工作,我对它的运行没有任何问题(只是,它的主体与我的问题无关,所以我没有提供它)。

我认为在其源代码中对数十个不同类进行硬编码装饰并不是一个最佳主意,并且正在寻找规范的解决方案。

4

1 回答 1

0

一般来说,没有什么神奇的方法可以让代码知道一个 api 等同于另一个。

但是,python 中用于过程生成类的机制是元类和类装饰器。您可以使用一个元类,它使用您提供的一些信息来生成另一个类。这是一个很好的介绍:http ://eli.thegreenplace.net/2011/08/14/python-metaclasses-by-example/

由于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
于 2013-09-18T17:02:38.890 回答