2017-01-03 51 views
0

我開始建立我class以這種方式(更像是一個普通function):Python類 - 鏈的實例方法

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 methodsinstance 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可以一次運行(實例化)?

+0

你的意思是'test.output(test.filter_api(test.search_api ()))'? – chepner

+0

如何在'ex2'中使用方法中的參數?我無法想象在這種情況下它會做你想要的。 –

+0

這沒有任何意義。你的'__init__'是多餘的,因爲它沒有超過超類的作用,並且沒有任何方法使用'self',所以它們可能完全是正常的函數。 – RemcoGerlich

回答

1

無需神奇的東西,如果你需要對象的行爲像函數調用,應實現__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()) 
+0

你會得到'TypeError:__init __()應該返回None' – RemcoGerlich

+0

是的,這就是我沒有審查我的答案張貼,編輯答案。謝謝@RencoGerlich – yorodm

+0

所有答案都是有效的,但我認爲這是最簡單的。 –

2

我想你以後是建設者模式,所以你可以寫output = Search().filter().get_output()或類似的東西。

對於這個工作,你需要從所有的「中間」的方法返回生成器對象:

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 
1

一些助手,使其編譯:

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() 
1

您可以使用__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()