pythonのカスタムクラスでfuth object()をf 'as f'の使用を実装する
-
04-10-2019 - |
質問
Pythonでファイルのようなオブジェクトを開いて( /dev /dev /を介したシリアル接続)、閉じる必要があります。これは、私のクラスのいくつかの方法で数回行われます。私がそれをしていた方法は、コンストラクターにファイルを開いてから、デストラクタで閉じることでした。私は奇妙なエラーが発生していますが、それはゴミコレクターなどに関係していると思います。私はまだ自分のオブジェクトが削除されているかを正確に知らないことに慣れていません=
私がこれをしていた理由は、私が使用しなければならないからです tcsetattr
私がそれを開くたびに多数のパラメーターを使用すると、それはあちこちですべてをするのが迷惑になります。だから私はそれを使うことができるようにすべてを処理するために内側のクラスを実装したい
with Meter('/dev/ttyS2') as m:
私はオンラインで探していました、そして私はどのようにする方法について本当に良い答えを見つけることができませんでした with
構文が実装されています。私はそれが使用しているのを見ました __enter__(self)
と __exit(self)__
方法。しかし、これらのメソッドを実装しなければならないのはすべて、構文を使用することができますか?それともそれ以上ありますか?
これを行う方法に関する例や、それがすでに見られるファイルオブジェクトにどのように実装されているかについてのドキュメントのいずれかがありますか?
解決
これらの方法は、オブジェクトを使用するために必要なすべてです with
声明。
の __enter__
ファイルオブジェクトを開いてセットアップした後、ファイルオブジェクトを返す必要があります。
の __exit__
ファイルオブジェクトを閉じる必要があります。それを書くためのコードは with
ステートメントボディ。
class Meter():
def __init__(self, dev):
self.dev = dev
def __enter__(self):
#ttysetattr etc goes here before opening and returning the file object
self.fd = open(self.dev, MODE)
return self.fd
def __exit__(self, type, value, traceback):
#Exception handling here
close(self.fd)
meter = Meter('dev/tty0')
with meter as m:
#here you work with the file object.
m.read()
他のヒント
最も簡単なのは、標準のPythonライブラリモジュールを使用することです ContextLib:
import contextlib
@contextlib.contextmanager
def themeter(name):
theobj = Meter(name)
yield theobj
theobj.close() # or whatever you need to do at exit
これは作りません Meter
それ自体はコンテキストマネージャーです(したがって、そのクラスには非侵襲的です)が、むしろそれを「装飾」します(Pythonの「デコレーターの構文」という意味ではなく、むしろデコレーターのデザインパターンの意味ではほとんどありませんが、 ;-)工場機能を備えています themeter
どれの は コンテキストマネージャー(それ contextlib.contextmanager
デコレーターは「単一 - から構築されます -yield
「あなたが書くジェネレーター機能) - これはそれを作ります それで 侵入条件と出口条件を分離するのがはるかに簡単で、ネストを避けます。
最初のGoogleヒット(私にとって)は、それを十分に説明しています:
http://effbot.org/zone/python-with-statement.htm
そして、PEPはそれをより正確に説明します(ただし、より冗長にも):