微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python装饰器的早期解析破坏了前向声明

如何解决Python装饰器的早期解析破坏了前向声明

我在系统中有一些对象,他们需要知道下一个对象是谁。每个函数都有一个do_process()函数,该函数必须在完成后返回下一个类。

class A():
    def do_process(self):
        # dosomestuff
        return B(self)

class B():
    def do_process(self):
        # dosomestuff
        return C(self)

class C():
    def do_process(self):
        # dosomestuff
        return A(self)

a = A()
b = a.do_process()
c = b.do_process()
a2 = c.do_process()

然后我注意到我的所有函数返回时都执行相同的操作,因此我应该为此真正编写一个装饰器。我想整理一下do_process的最后一行,以明确表示它将使用装饰器返回,以使内容更清晰,如下所示:

@next_process(B) # tell the reader up front that the next object is a B thing
def do_process
   # do some stuff
   # next_process decorator returns an instance of B for us

在我的实现中,构造函数需要几个args,但它始终是相同的args,因为在我的代码中,A,B,C覆盖了基类。一个经典的Factory模式问题。但是,我立即遇到麻烦,因为装饰器开始在A类中解析它,而B尚未声明。我也很讨厌编写装饰器,所以我写了一个Factory,希望用字符串“ B”替换B,以便工厂在运行时向装饰器提供下一个对象。但这很糟糕,因为只有在完全声明B后,我才能将B类添加到我的工厂中。但是,装饰者希望已经获得B的副本,它实际上仍在解析A的同时调用了我的工厂,因此它在工厂或任何人真正了解B之前就已经调用了我的工厂(类A本身,甚至没有在以下位置在Factory中注册)这一点)。

class A()
   @next_decorate(next=factory("B"))  # <= blows up because the factory has not yet got a way to return class B
   def do_process(self)
      # do some stuff

我对为什么它在C ++中起作用不感兴趣,我已经忘记了如何在C ++中编写宏和工厂。我想知道,我应该坚持不懈地保持工厂的可维护性,以后再学习编写更复杂的装饰器。还是我缺少像这样的紧密联接的更多Pythonic解决方案?

解决方法

您应该真正停止使用C ++术语进行思考。通常,您几乎不需要编写工厂,只需一个简单的映射即可。预先编写您的装饰器,将字符串版本作为参数,但在内部使用映射。

0s

请注意,如果继续创建一些0s类,则适用相同的原理。只需在内部使用该工厂即可。还是不要让它热心评估。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。