1. ホーム
  2. python

[解決済み] Pythonのカスタムクラスで'with object() as f'を使用するための実装

2022-12-24 12:04:41

質問

Pythonでファイルのようなオブジェクトを開き(/dev/を介したシリアル接続です)、それを閉じなければなりません。これは私のクラスのいくつかのメソッドで数回行われます。私は、コンストラクタでファイルを開き、デストラクタでそれを閉じるという方法をとっていました。しかし、私は奇妙なエラーを受け取っていて、それはガベージコレクタとそのようなものに関係していると思います。

これをやっていた理由は、私は tcsetattr を使う必要があり、それをあちこちで行うのは面倒だからです。そこで、それをすべて処理するインナークラスを実装して、次のように使うことができるようにしたいのです。

with Meter('/dev/ttyS2') as m:

ネットで調べていたのですが、本当に良い答えが見つかりませんでした。 with 構文がどのように実装されているかについての良い答えは見つかりませんでした。私が見たのは、それが __enter__(self)__exit(self)__ というメソッドがあります。しかし、これらのメソッドを実装するだけで、with構文を使用できるようになるのでしょうか?それとも、それ以上のことがあるのでしょうか?

これを行う方法についての例か、私が見ることができるファイルオブジェクトにすでに実装されている方法についてのドキュメントはありますか?

どのように解決するのですか?

これらのメソッドは、オブジェクトを 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
    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.fd.read()