我有很多课程,为不同的网站实现了一些常规任务:
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()装饰器正在工作,我没有问题它的功能(只是,它的身体与我的问题无关,所以我没有提供它)。
我认为在他们的源代码中对几十个不同类的硬编码装饰并不是最好的主意,并且正在寻找规范的搜索。
答案 0 :(得分:0)
一般来说,没有神奇的方法让代码知道一个api等同于另一个。
然而,python中用于程序生成类的机制是元类和类装饰器。您可以使用元类,它使用您提供的某些信息来生成另一个类。 这是一个很好的介绍:http://eli.thegreenplace.net/2011/08/14/python-metaclasses-by-example/
由于python" duck typing",抽象类很少是必需的,而且有一些代码味道。您可能只需重新设计代码,以便不需要重命名和抽象类。特别是,如果您的代码需要更改,则需要更改。如果你要包装外部代码以使几个不同的apis兼容,我只会这样做。
类似的东西:
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