blank page

プログラミングなどについて書きます

n日ほど経ったので一応報告

n日ほど経ったので一応報告✋ 自動車学校卒業しました. いや割とマジな方で😆 いや, ほんとウケる. 未だに信じられない 😉

卒業しました

MTを頑張りました.
3ヶ月くらいちまちま行って, 延長なく無事終わりましたとさ. めでたしめでたし.

pythonのwith文を勉強する part2

nve3pd.hatenablog.com

この記事の続きを書いています.

ここでいうpythonはpython3のお話です.
クリスマスなんてものはなかった:cry:

withのブロックの中で例外が起こったら...

スイートが例外によって終了されたのなら、その例外の型、値、トレースバックが exit() に引数として渡されます。そうでなければ、 3 つの None 引数が与えられます。
スイートが例外により終了され、 exit() メソッドからの戻り値が偽(false)ならば、例外が再送出されます。この戻り値が真(true)ならば例外は抑制され、実行は with 文の次の文から続きます。
もしそのスイートが例外でない何らかの理由で終了した場合、その exit() からの戻り値は無視されて、実行は発生した終了の種類に応じた通常の位置から継続します。

試してみる

class Test_with:
    def __init__(self):
        print("__init__")

    def __enter__(self):
        print("__enter__")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("exc_type: ", exc_type)
        print("exc_value: ", exc_value)
        print("traceback: ", traceback)
        print("__exit__")
        return True
        #return False

    def __del__(self):  # ついでに書いた
        print("__del__")

    def say(self):
        print("Hello!")


def main():
    print("*** start main function ***")
    with Test_with() as test:
        print("test: ", test)
        print("*** start `with` ***")
        test.say()
        raise ValueError(int)
        print("*** end `with` ***")
    print("*** end main function ***")


if __name__ == "__main__":
    main()

出力結果

__exit__がTrueを返した場合

*** start main function ***
__init__
__enter__
test:  <__main__.Test_with object at 0x7f0d1adf1b70>
*** start `with` ***
Hello!
exc_type:  <class 'ValueError'>
exc_value:  <class 'int'>
traceback:  <traceback object at 0x7f0d1adf7988>
__exit__
*** end main function ***
__del__
#### 

__exit__がFalseを返した場合

*** start main function ***
__init__
__enter__
test:  <__main__.Test_with object at 0x7fe8636ddb70>
*** start `with` ***
Hello!
exc_type:  <class 'ValueError'>
exc_value:  <class 'int'>
traceback:  <traceback object at 0x7fe8636e3988>
__exit__
Traceback (most recent call last):
  File "hoge.py", line 36, in <module>
    main()
  File "hoge.py", line 30, in main
    raise ValueError(int)
ValueError: <class 'int'>
__del__

追いかけます

スイートが例外によって終了されたのなら、その例外の型、値、トレースバックが exit() に引数として渡されます。そうでなければ、 3 つの None 引数が与えられます。そうでなければ、 3 つの None 引数が与えられます。

例外が発生すると __exit__ の引数に渡されているのが出力結果からわかります.
また,例外を発生させていない場合は前回の記事をみてわかる通りNoneが入っていますね.

スイートが例外により終了され、 exit() メソッドからの戻り値が偽(false)ならば、例外が再送出されます。

__exit__ がFalseを返した時はexitを抜けたあとに例外が発生しているのがわかりますね.

戻り値が真(true)ならば例外は抑制され、実行は with 文の次の文から続きます

__exit__がTrueを返した時は, 例外が消えてwith文の次の文から実行されて言ってるのがわかります.

もしそのスイートが例外でない何らかの理由で終了した場合、その exit() からの戻り値は無視されて、実行は発生した終了の種類に応じた通常の位置から継続します。

らしいです.

最後に

ここはどう使っていくのがいいのかがあまりイメージできていないので誰かおしえてもらえると幸いです.
あと,前回の記事に比べてだいぶ雑な感じになってしまい申し訳ないです:sorry:

参考文献

8. 複合文 (compound statement) — Python 3.6.3 ドキュメント

5. 組み込み例外 — Python 3.6.3 ドキュメント

3. データモデル — Python 3.6.3 ドキュメント

pythonのwith文を勉強する

ここでのpythonはすべてpython3です.


こんにちは. 冬休みに入りますが遊んでくれる人がいないのでpythonのwith文を調べます。

with構文とはなにか

with 文は、ブロックの実行を、コンテキストマネージャによって定義されたメソッドでラップするために使われます。

8. 複合文 (compound statement) — Python 3.6.3 ドキュメント

Example

with open("hoge.txt", "w") as f:
    f.write("Hello World!")

# 上記のコード等価です
# f = open("hoge.txt", "w")
# f.write("Hello World!")
# f.close()

with文の動き

  1. コンテキスト式を評価することで,コンテキストマネージャを取得
  2. コンテキストマネージャの __exit__() メソッドが、後で使うためにロードされる
  3. コンテキストマネージャの __enter__() メソッドが呼ばれる
  4. with文にターゲットが含まれていたら, それに __enter__() からの戻り値が代入される
  5. スイートが実行
  6. コンテキストマネージャの __exit__() が呼ばれる(以下略)

8. 複合文 (compound statement) — Python 3.6.3 ドキュメント

らしいです.
with文が使えるのは __enter____exit__ が定義されているclassらしいです.
:thinking_face: って感じなので実際に書いて動かしてみます.

試してみる

class Test_with:
    def __init__(self):
        print("__init__")

    def __enter__(self):
        print("__enter__")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("__exit__")
        print("exc_type: ", exc_type)
        print("exc_value: ", exc_value)
        print("traceback: ", traceback)

    def __del__(self):
        print("__del__")

    def say(self):
        print("Hello!")


def main():
    print("*** start main function ***")
    with Test_with() as test:
        print("test: ", test)
        print("*** start `with` ***")
        test.say()
        print("*** end `with` ***")
    print("*** end main function ***")


if __name__ == "__main__":
    main()

出力結果は以下になります.

*** start main function ***
__init__
__enter__
test:  <__main__.Test_with object at 0x7f257ec15978>
*** start `with` ***
Hello!
*** end `with` ***
__exit__
exc_type:  None
exc_value:  None
traceback:  None
*** end main function ***
__del__

with文の動きというセクションで引用した説明と一緒に動きを追ってみます.

おいかけます

コンテキスト式を評価することで,コンテキストマネージャを取得

コンテキストマネージャは __enter____exit__ メソッドを持つオブジェクトです.
コンテキストマネージャについては

Pythonのコンテキストマネージャは何が嬉しいのか? - Qiita

が詳しく書かれています.

Test_withクラスをインスタンス化してコンテキストマネージャとして取得してるっぽいです.(多分)
なので, 出力結果を見ると __init__ がまず呼ばれていることがわかります.


コンテキストマネージャの __exit__ メソッドが, 後で使われるためにロードされる

ロードされてるらしいです.


コンテキストマネージャの __enter__ メソッドが呼ばれる.

出力結果で __init__ の次に __enter__ が表示されているので __enter__ メソッドが呼ばれていることがわかります.


with文にターゲットが含まれていたら, それに __enter__メソッドからの戻り値が代入される

__enter__self を返したので, with文のところの as で指定した test__enter__ の返り値が代入されています.


スイートが実行

with文のブロック内の処理が実行されています.


コンテキストマネージャの __exit__メソッドが呼ばれる

出力結果を見るとwith文のブロック内の処理が終わってから __exit__メソッド内で定義した処理が実行されているので, __exit__ メソッドが呼ばれていることがわかりますね.

まとめ

with文良さ.
また今度, 説明の部分の(以下略)を追っていきます.

(以下略部分を適当に書きました)
nve3pd.hatenablog.com

参考文献

8. 複合文 (compound statement) — Python 3.6.3 ドキュメント
3. データモデル — Python 3.6.3 ドキュメント
Pythonのコンテキストマネージャは何が嬉しいのか? - Qiita

httpstatをNimで実装してみた

Nimとは?



Pythonのような生産性とCのような速度を持つことを目標とした言語.

Nimの簡単な紹介 - Qiita

Nim programming language | Nim


httpstatとは?


github.com

curlのラッパーで,レスポンスタイムを見やすく表示してくれる便利なやつ.


例のブツ


Python, go, shell script, javascript, PHPなどはあったものの,Nim実装がなかったので勉強がてら実装してみました.

github.com

Python実装を参考にして書いたらめちゃくちゃPythonっぽくなって(Pythonっぽくかけて)すごいな〜という気持ちです :smile:
Nimっぽい実装ができていないと思うのでpull requestお待ちしています