質問するログイン新規登録
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3089閲覧

globalを用いて取り込んだ変数がmypyでundefined扱いになる

namuyan

総合スコア76

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/08/17 02:25

0

1

外部で定義された変数をglobalで関数内に取り込み操作します。
下記の例文は実際に動作しますがmypyが通りません。

python

1def uniq_id_generator() -> Callable[[], int]: 2 lock = Lock() 3 uuid = 0 4 def get_uuid() -> int: 5 global uuid 6 with lock: 7 uuid += 1 8 return uuid 9 return get_uuid 10 11 12def main(): 13 get_uuid = uniq_id_generator() 14 id1 = get_uuid() 15 id2 = get_uuid()

error

1test.py:7: error: Name 'uuid' is not defined 2test.py:8: error: Name 'uuid' is not defined

このようなエラーが出ます。構文としては簡単だし短いので# type: ignoreを付け加えてスキップしています。しかし、他に方法はあるのならば知りたいです。

何かわかる方は回答の方をよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

globalは本当のグローバル(外側の関数の定義よりもさらに外)で定義された変数に対して使うものです。
グローバルでuuidが定義されていないからエラーとなっているのではないでしょうか。

今回のケースだと、globalの代わりにnonlocalを使うべきです。

投稿2020/08/17 02:47

bsdfan

総合スコア4932

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

namuyan

2020/08/17 03:07

globalに関して勘違いしていました。確かにこの場合の用途としては一般的に用いたい変数でもないのでnonlocalが正しそうです。
guest

0

ベストアンサー

掲載のコードだけを考慮すると"これは動作しないな"と思いますし、実際動作しません。
つまりmypyの指摘は正しいです。

逆に言うと実際に動作するならば、質問に載っていないところに動作する理由があります。
質問には単体で実行可能なコードを載せてください。

python

1def uniq_id_generator(): 2 uuid = 0 3 4 def get_uuid(): 5 global uuid 6 uuid += 1 7 return uuid 8 9 return get_uuid 10 11 12def main(): 13 get_uuid = uniq_id_generator() 14 id1 = get_uuid() 15 id2 = get_uuid() 16 17 18main()

実行結果

plain

1Traceback (most recent call last): 2 File "(略)/aa.py", line 14, in <module> 3 main() 4 File "(略)/aa.py", line 11, in main 5 id1 = get_uuid() 6 File "(略)/aa.py", line 5, in get_uuid 7 uuid += 1 8NameError: name 'uuid' is not defined

勝手に想像すると、どこかにglobalで宣言して代入する関数があって、"それを先に呼ばなければならない"という約束事が暗黙的にできてしまっているのではないでしょうか。

これは動く

def getter(): global g return g def initializer(): global g g = 0 initializer() print(getter())

これは動かない

def getter(): global g return g def initializer(): global g g = 0 print(getter())

「関数の呼び出し順によって動かなかったりする」とmypyが指摘してくれている、と考えた方がよいかと。

投稿2020/08/17 02:49

quickquip

総合スコア11353

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

namuyan

2020/08/17 03:04

REPLで関数の上書きを何度か繰り返してテストしていましたがそれが間違いの元だったのかもしれませんね。どこかでuuidが代入されていたのかもしれません。もう一度手元で試してみましたが動作しませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問