こんにちは。明月です。
この投稿はPythonでglobalとnonlocalに関する説明です。
以前の投稿でクロージャ(closure)に関して説明したことがあります。
link - [Python] 06. 関数(function) - インライン関数、callbak、ラムダ(lambda)そしてクロージャ
クロージャとはインライン関数で関数の外部から宣言したデータを持ち込むということです。
# 変数宣言
data = "hi!!"
# 関数生成
def example_function():
# example_functionではdata変数を宣言してないが、外部のdataの変数を使える。
print(data)
# 関数呼び出す。
example_function()
でも外部から宣言したデータを関数の内部で修正することはどうでしょう。
# 変数宣言
data = "hi!!"
# 関数生成
def example_function():
# 外部dataの変数の値を修正する。
data = "hello"
# 関数呼び出す。
example_function()
# コンソール出力
print(data)
example_function関数の内部でdataの値をhelloに変更しましたが、外部でコンソール出力するとデータが変更されないでした。
理由はexample_functionの中でdata="hello"したことは内部変数に認識して新しい変数を宣言したからです。
そうすると、仕様によってグローバル変数を関数の内部で変更する時もありますが、その時にはどうでしょう。
# 変数宣言
data = "hi!!"
# 関数生成
def example_function():
# global宣言で外部変数を参照できるように設定
global data
# グローバル変数に格納
data = "hello"
# 関数を呼び出す。
example_function()
# コンソール出力
print(data)
今回はdataの変数の値がちゃんと変更されました。
今回はインライン関数関数で使いましょう。
# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
# 変数宣言
data = "hi!!"
# インライン関数生成
def inline_function():
# data変数はこの状況で一番近いステップのexample_functionのdata変数だ。
print(data)
# インライン関数を呼び出す。
inline_function()
# 関数を呼び出す。
example_function()
上のグローバル変数でdata変数があり、example_functionの関数の中でもdata変数があります。
その状況でinline_function関数でdata変数を参照すれば、inline_function関数の一番近いステップの変数を参照します。
グローバル変数よりexample_functionの変数がもっと近いステップということです。
でも、使用によってグローバル変数を使いたいです。
# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
# 変数宣言
data = "hi!!"
# インライン関数生成
def inline_function():
# globalを宣言すればグローバル変数を参照することになる。
global data
# コンソール出力
print(data)
# インライン関数を呼び出す。
inline_function()
# 関数を呼び出す。
example_function()
そうすればinline_function中でもglobal関数を修正ができます。global dataをしてdata ="値"をいれば修正できます。
それなら、inline_function中でexample_functionのデータはどのように修正するでしょう?
単純にdata="値"を入れれば初めの例みたいにinline_function関数のデータに宣言されてしまいます。
# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
# 変数宣言
data = "hi!!"
# インライン関数生成
def inline_function():
# nonlocalを使えば、example_functionのデータを参照できる。
nonlocal data
# 変数修正
data = "hello"
# インライン関数を呼び出す。
inline_function()
# コンソール出力
print(data)
# 関数を呼び出す。
example_function()
globalはグローバル変数をnonlocalは一番近いステップの変数を参照することです。
そうすればインライン関数の中でインライン関数でグローバル変数ではないけど、一番トップにある変数を修正したいです。
# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
# ここの変数を修正したい。
data = "hi!!"
# インライン関数生成
def inline_function():
# 変数宣言
data = "third?"
# インライン関数生成
def inline2_function():
# nonlocalはinline_functionのdata変数を参照。
nonlocal data
# 変数修正
data = "hello"
# インライン関数を呼び出す。
inline2_function()
# インライン関数を呼び出す。
inline_function()
# コンソール出力
print(data)
# 関数を呼び出す。
example_function()
そこまでは参照ができないです。(何処まで参照したいのか?)
実は上みたいにソースを作成するとプログラム設計を考えなければならないです。可読性がすごく悪いですから。。。
ここまでPythonでglobalとnonlocalに関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [Python] 15. クラスを継承する方法2020/06/15 18:20:07
- [Python] 14. クラスプロパティ(Property)2020/06/12 17:45:13
- [Python] 13. クラス関数(class method)とダック・タイピング、そして特殊メソッド2020/06/11 19:42:29
- [Python] 12. クラス(Class)を使う方法2020/06/10 19:33:33
- [Python] 11. デコレーター(Decorator)を使う方法2020/06/09 17:27:18
- [Python] 10. モジュールとパッケージ(import)2020/06/08 19:07:50
- [Python] 09. 例外処理する方法2020/06/05 17:11:47
- [Python] 08. ジェネレータ(Generator)2020/06/04 18:46:08
- [Python] 07. globalとnonlocal2020/06/03 20:34:49
- [Python] 06. 関数(function) - インライン関数、callbak、ラムダ(lambda)そしてクロージャ2020/06/02 20:51:22
- [Python] 05. コンプリヘンション(Comprehension)を使用する方法2020/06/01 19:38:58
- [Python] 04. 制御文(if, while, for, break, continue)とインデント2020/05/29 21:09:08
- [Python] 03. Pythonでリスト(list)とタプル(tuple)、そしてディクショナリ(dictionary)、セット(set)2020/05/27 18:49:08
- [Python] 02. データタイプ、変数宣言そしてコメントする方法2020/05/26 18:16:52
- [Python] 01. Python3をインストールする方法(Anacondaインストール)2020/05/25 19:02:44
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07