3

現在取り組んでいるプロジェクトに SimPy シミュレーションを追加しようとしていますが、バージョン 3 のリリース/リクエストについて混乱しています。

問題なく「with」ブロックを使用してリソースを実装できましたが、私の状況では、「with」ブロックを使用せずにリソースを要求/解放したいと考えています。

ただし、SimPy 3 を使用してこの例を見つけることができません。リソースに関するドキュメント/ソースを読みましたが、まだ正しく理解できません。誰かが適切な方法を説明できますか:

...
Request a Resource with the method: 'request()'
...
Release that Resource with the method: 'release()'
...

ありがとう、お手数をおかけして申し訳ありません。

PS: Resources.resource を使用するつもりです

4

3 に答える 3

5

ブロックなしでリソースを使用したい場合with(そして、中断されないことがわかっている場合)、次のようにします。

req = resource.request()
yield req
# do stuff
resource.release(req)
于 2014-05-19T07:03:06.287 に答える
3

ブロックに入ったとき、およびブロックを離れるときにwithオブジェクト呼び出しを使用します。だからあなたがするとき__enter__with__exit__

res = resource.Resource()
with res.request() as req:
  # stuff

あなたは実際__enter__に Request オブジェクトを呼び出しており、次のように#stuff呼び出してい__exit__ます。

class Request(base.Put):
    def __exit__(self, exc_type, value, traceback):
        super(Request, self).__exit__(exc_type, value, traceback)
        self.resource.release(self)

class Put(Event):  # base.Put
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        # If the request has been interrupted, remove it from the queue:
        if not self.triggered:
            self.resource.put_queue.remove(self)

したがって、withブロックは次と同等です。

res = resource.Resource(...)
req = res.request()
#stuff
if not req.triggered:
   res.put_queue.remove(req)
   res.release(req)

ただし、withブロックは、実行中にどのような例外がスローされても、クリーンアップ コードが確実に呼び出されるようにし#stuffます。上記のコードではそれが失われます。

于 2014-05-18T22:51:04.907 に答える
0

それはすべてPEP343で概説されています。

with EXPR as VAR:
        BLOCK

になります:

mgr = (EXPR)
exit = type(mgr).__exit__  # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
    try:
        VAR = value  # Only if "as VAR" is present
        BLOCK
    except:
        # The exceptional case is handled here
        exc = False
        if not exit(mgr, *sys.exc_info()):
            raise
        # The exception is swallowed if exit() returns true
finally:
    # The normal and non-local-goto cases are handled here
    if exc:
        exit(mgr, None, None, None)

これはまさにPythonがwith... as...ブロックを使用する方法ですが、これらを使用したくない理由があると思います。その場合は、__enter__and__exit__関数だけが必要です。私が考える方法は、__enter__すべてをセットアップし、__exit__すべてのクリーンアップを行うことです。

于 2014-05-18T22:55:04.127 に答える