Python class - 链接实例方法

Python class - chaining instance methods

我已经开始以这种方式构建我的 class(更像是一个常规的 function):

ex 1

  class Child(Parent):

    def __init__(self,user):
        Parent.__init__(self, user)     

        search = api.search() 
        filter = api.filter(search)
        output = api.output(filter)

        return output

这样我可以 运行:

movies = Child('John')

并获得我的最终输出。

然后,为了更好地控制数据,我将 global api methods 分解为 instance methods

ex 2

  class Child(Parent):

    def __init__(self,user):
        Parent.__init__(self, user)     

    def search_api(self):
       search = api.search() 
       return search    

    def filter_api(self, search):
       filter = api.filter(search)
       return filter

    def output(self, filter):
       output = api.output(filter)  
       return output

现在我必须在不同的实例中打破它,以获得最终输出:

test = Child('John')
search = test.search_api()
filter = test.filter_api(search)
out = test.output(filter)

print (out)

是否有 decoratorbuilt-in method 允许我链接所有 instance methods 以便 ex2 可以一次 运行 (实例化) ?

我认为您追求的是构建器模式,因此您可以编写 output = Search().filter().get_output() 或类似的东西。

为此,您需要 return 来自所有 "intermediate" 方法的构建器对象:

class Search(object):
    def __init__(self, *args, **kwargs):
        # apply args, kwargs

    def filter(self, *args, **kwargs):
        # apply args, kwargs
        self.filters.append(...)
        return self

    def paginate(self, *args, **kwargs):
        # apply args, kwargs
        self.pagination = ...
        return self

    def get_output(self, *args, **kwargs):
        # apply args, kwargs
        # build the search, find output ...
        return output

如果您需要使对象表现得像函数调用,则不需要神奇的东西,您应该实现 __call__ 而不是将所有内容打包到构造函数中。:

class Child(Parent):

    def __init__(self,user):
        Parent.__init__(self, user)
        self.myuser = user


    def search_api(self):
       search = api.search() 
       return search    

    def filter_api(self, search):
       filter = api.filter()
       return filter

    def output(self, filter): 
       return output

    def __call__(self,user):
        search = self.search_api()
        filter = self.filter_api(search)
        return self.output(filter)

现在您可以:

a = Child('Joe')
print(a())

编译的一些助手:

class API:
    def __getattr__(self, attr):
        return API()
    def __call__(self, x=1):
        return 42

api = API()

class Parent(object):
     def __init__(self, user):
        self.user = user

执行 process 方法中的所有步骤:

class Child(Parent):

    def __init__(self, user):
        super().__init__(user)     

    def search_api(self):
        search = api.search() 
        return search    

    def filter_api(self, search):
        filter = api.filter()
        return filter

    def output(self, filter):   
        return api.output

    def process(self):
        res = self.search_api() 
        res = self.filter_api(res)
        return self.output(res)

允许您在一行中完成所有操作:

movies = Child('John').process()

您可以使用 __call__()。我知道这不一样,但也许它可能比你的 ex2:

class Child(Parent):

    def __init__(self, user):
        Parent.__init__(self, user)

    def search_api(self):
        search = api.search() 
        return search    

    def filter_api(self, search):
        filter = api.filter(search)
        return filter

    def output(self, filter):
        output = api.output(filter)  
        return output

    def __call__(self):
        search = self.search_api()
        filter = self.filter_api(search)
        return self.output(filter)

然后,你可以这样做:

c = Child("john")
output = c()