2017-08-04 3 views
1

がasyncioループと非同期コルーチンを含むクラスの次の例を考えてみましょう:パイソン、asyncio:ループ構文を簡素化するクラスのデコレータ

import asyncio 

class Async: 
    def __init__(self): 
     self.loop=asyncio.get_event_loop() 

    async def function(self, word): 
     print(word) 
     await asyncio.sleep(1.0) 

a=Async() 
a.loop.run_until_complete(a.function("hello_world")) 

これは、作業を行います。
私は次のことを試してみました私は

a.function("hello_world") 

functionを呼び出すコードの構文を簡素化することができるようにデコレータを作成したいと思います:

class Async: 
    def __init__(self): 
     self.loop=asyncio.get_event_loop() 

    def async_loop(f): 
     def decorated(*args, **kwargs): 
      self.loop.run_until_complete(f(*args, **kwargs)) 

    @async_loop 
    async def function(self, word): 
     print(word) 
     await asyncio.sleep(1.0) 

a=Async() 
a.function("hello_world") 

私はエラーが表示されるその時点で:'NoneType' object is not callable 。私はクラスの外でデコレータ機能を持っているようにもしようとしましたが、私は同じエラーを受けました。デコレータ機能が最も優れているかどうかは、(メソッドとしての)claassの内側にあるのか、外部にあるのかは分かりません。 私は非常にPythonに新しく、クラスのAsyncio、デコレータ、デコレータはまだ私にとってはかなり混乱しています。どんな良い魂も、そのコードを正しく行う方法を知っているだろうか?

+0

あなたはClassic Blundersの1つをコミットしました。 'async_loop'は'装飾された 'を返さなければなりません。 – PaulMcG

+0

@PaulMcG OKはい - 私は 'self.loop'に関連した他のエラーを受け取りました。それは私のためにクラスでデコレータを行う方法がまだまだとても混乱しているので、ここで大いに助けになるでしょう –

答えて

1

selfはいたる所に忍び込んでいるので、クラス内のデコレータは混乱しています。ここで

はあなたのコードの作業バージョンです:

import asyncio 

class Async: 
    def __init__(self): 
     self.loop=asyncio.get_event_loop() 

    def async_loop(f): 
     def decorated(self, *args, **kwargs): 
      self.loop.run_until_complete(f(self, *args, **kwargs)) 
     return decorated 

    @async_loop 
    async def function(self, word): 
     print(word) 
     await asyncio.sleep(1.0) 

a=Async() 
a.function("hello_world") 

あなただけのより良いasync_loop内部イベントループを宣言する場合、またはクラスの外でデコレータを宣言し、それはより多くの「無私」を作ることができます。

def async_loop(f): 
    loop = asyncio.get_event_loop() 
    def decorated(*args, **kwargs): 
     loop.run_until_complete(f(*args, **kwargs)) 
    return decorated 

class Async: 
    @async_loop 
    async def function(self, word): 
     print(word) 
     await asyncio.sleep(1.0) 

a=Async() 
a.function("hello_world") 

これで、「なぜこれがクラスの最初の場所にあるのですか」という質問が発生し始めます。そしてもう一つの質問は、「すでにこれを行うデコレータはありませんか?」

+0

恐ろしいthx。なぜasync_loop()はasync_loop(self、f)である必要がありますか?それはまだ非同期クラスのメソッドとみなされますか? –

+0

良い質問です。定義されているように、それはまだAsyncインスタンスへのバインドされたメソッドであり、私が "f"と呼ぶものは実際には "self"でなければなりません。クラス内のデコレータはおそらくstaticメソッドでなければならないでしょう。 "クラス内のデコレータはあまりいい考えではないかもしれません。私の編集を参照してください。 – PaulMcG

+0

これを行うデコレータを知っていますか? 。 –