Python decorator早期解析会破坏转发声明

Python decorator早期解析会破坏转发声明,python,decorator,Python,Decorator,我在一个系统中有一些对象,它们需要知道下一个队列是谁。每个类都有一个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_p

我在一个系统中有一些对象,它们需要知道下一个队列是谁。每个类都有一个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_过程中的最后一行,以清楚地表明它将使用装饰器返回以保持清晰,因此它的内容如下:

@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
在我的实现中,构造函数接受几个参数,但总是相同的参数,因为我的代码中的a、B、C重写了基类。一个典型的工厂模式问题。但是,我立即遇到了麻烦,因为装饰程序开始在类A中解析这个,而B还没有声明。我也不擅长编写装饰器,所以我编写了一个工厂,希望用字符串“B”替换B,让工厂在运行时向装饰器提供下一个对象。但这很糟糕,因为我只能在B完全声明后将B类添加到我的工厂中。然而,装饰程序已经想要得到B的一个副本,它实际上在解析a的同时调用了我的工厂,因此它在工厂之前调用了我的工厂,或者任何人实际上知道B(类a本身,在这一点上甚至没有在工厂中注册)

A类()

Next Ext装饰(下一个工厂(B))你应该真正停止用C++术语思考。您几乎不需要编写工厂,通常只需简单的映射即可。提前编写以字符串版本作为参数的装饰器,但在内部使用映射

def next_process(next_):
    def deco(func):
        def wrapper(self, *args, **kwargs):
            func(self, *args, **kwargs)
            return MAP[next_](self)
        return wrapper
    return deco

class Process:
    def __init__(self, prev_process):
        self.prev_process = prev_process

class A(Process):
    @next_process('B')
    def do_process(self):
        # dosomestuff
        return B(self)

class B(Process):
    @next_process('C')
    def do_process(self):
        # dosomestuff
        return C(self)

class C(Process):
    @next_process('A')
    def do_process(self):
        # dosomestuff
        return A(self)

MAP = {'A': A, 'B':B, 'C':C}

注意,如果您继续创建一些
工厂
类,同样的原则也适用。只需在内部使用该工厂。或者不要急于对其进行评估。

只需按相反的顺序定义它们?@juanpa.arrivillaga这是我简单的直接解决方案,就是这样做的。这些类是selenium页面对象,我不想被困在创建引用圈的过程中,因此工厂模式就像是一条尝试的路线。谢谢@juanpa。这正是我想要的,我的解释要么还可以,要么你很擅长拼图。在我遗漏的基类上扩展的额外分数。我的应用程序中的每个类都是一个Selenium页面对象,因此我需要一个装饰器,以便一个页面指向另一个页面<代码>@next_process('A')def do_process(self):#dosomestuff返回self#
def next_process(next_):
    def deco(func):
        def wrapper(self, *args, **kwargs):
            func(self, *args, **kwargs)
            return MAP[next_](self)
        return wrapper
    return deco

class Process:
    def __init__(self, prev_process):
        self.prev_process = prev_process

class A(Process):
    @next_process('B')
    def do_process(self):
        # dosomestuff
        return B(self)

class B(Process):
    @next_process('C')
    def do_process(self):
        # dosomestuff
        return C(self)

class C(Process):
    @next_process('A')
    def do_process(self):
        # dosomestuff
        return A(self)

MAP = {'A': A, 'B':B, 'C':C}