[Python] Python シリーズ チュートリアル -- Python3 の名前空間とスコープ (29)

序文

過去のレビュー:

公式文書の一節を見てみましょう。

名前空間は、名前からオブジェクトへのマッピングです。
現在、ほとんどの名前空間は Python 辞書として実装されています。

名前空間は名前からオブジェクトへのマッピングであり、ほとんどの名前空間は Python 辞書を通じて実装されます。

ネームスペースは、プロジェクト内での名前の競合を回避する方法を提供します。各名前空間は独立しており、関係がないため、名前空間が重複した名前を持つことはできませんが、異なる名前空間は影響を与えることなく重複した名前を持つことができます。

コンピュータ システムの例を見てみましょう。フォルダ (ディレクトリ) には複数のフォルダを含めることができます。各フォルダに同じファイル名を付けることはできませんが、異なるフォルダ内のファイルには同じ名前を付けることができます。

ここに画像の説明を挿入

通常、次の 3 つの名前空間があります。

  • ビルトイン名(ビルトイン名)、関数名abs、char、例外名BaseException、ExceptionなどのPython言語ビルトイン名。
  • グローバル名 (グローバル名) は、モジュール内で定義された名前であり、関数、クラス、その他のインポートされたモジュール、モジュール レベルの変数および定数を含むモジュールの変数を記録します。
  • ローカル名 (ローカル名) は、関数内で定義された名前であり、関数のパラメーターやローカルに定義された変数など、関数の変数を記録します。(クラスでも定義されています)

ここに画像の説明を挿入

名前空間の検索順序:

変数デモを使用すると仮定すると、Python の検索順序は、ローカル名前空間 -> グローバル名前空間 -> 組み込み名前空間です。

変数デモが見つからない場合は、諦めて NameError を発生させます。

NameError: name 'demo' is not defined。

名前空間のライフサイクル:

ネームスペースのライフサイクルはオブジェクトのスコープによって異なり、オブジェクトの実行が完了するとネームスペースのライフサイクルが終了します。

したがって、外部名前空間から内部名前空間のオブジェクトにアクセスすることはできません。

# var1 是全局名称

var1 = 5
def some_func():
 
    # var2 是局部名称
    var2 = 6
    def some_inner_func():
 
        # var3 是内嵌的局部名称
        var3 = 7

次の図に示すように、同じオブジェクト名が複数の名前空間に存在できます。

ここに画像の説明を挿入

範囲

スコープは、名前空間に直接アクセスできる Python プログラムのテキスト領域です。ここでの「直接アクセス可能」とは、名前への非修飾参照が名前空間内で名前を見つけようとすることを意味します。

スコープとは、Python プログラムが直接アクセスできる名前空間のテキスト領域です。

Python プログラムで変数に直接アクセスすると、変数が見つかるまですべてのスコープが内側から外側までアクセスされ、見つからない場合は未定義のエラーが報告されます。

Python では、プログラム変数にはどこからでもアクセスできるわけではなく、アクセス権は変数が割り当てられている場所によって異なります。

変数のスコープによって、プログラムのどの部分がどの特定の変数名にアクセスできるかが決まります。Python には次の 4 つのスコープがあります。

スコープは 4 つあります。

  • L (ローカル): 関数/メソッドの内部など、ローカル変数を含む最内層。
  • E (囲み): 非ローカル変数および非グローバル変数が含まれます。たとえば、2 つのネストされた関数、関数 (またはクラス) A に関数 B が含まれている場合、B の名前の場合、A のスコープは非ローカルになります。
  • G (グローバル): 現在のモジュールのグローバル変数など、現在のスクリプトの最も外側の層。
  • B (組み込み): 組み込みの変数/キーワードなどが含まれており、最終的に検索されます。

ルールの順序: L –> E –> G –> B。

ローカルで見つからない場合は、ローカルで見つけます (クロージャなど)。再度見つからない場合は、グローバルで見つけてから、組み込みで見つけます。

ここに画像の説明を挿入

g_count = 0  # 全局作用域
def outer():
    o_count = 1  # 闭包函数外的函数中
    def inner():
        i_count = 2  # 局部作用域

組み込みスコープは、builtin と呼ばれる標準モジュールによって実装されますが、変数名自体は組み込みスコープに組み込まれないため、このファイルを使用できるようにするには、このファイルをインポートする必要があります。Python 3.0 では、次のコードを使用して、どの変数が事前定義されているかを確認できます。

>>> import builtins
>>> dir(builtins)

Python では、モジュール、クラス、関数 (def、lambda) のみが新しいスコープを導入し、他のコード ブロック (if/elif/else/、try/excel、for/while など) は導入されません。新しいスコープは導入されません。つまり、これらのステートメントで定義された変数は、次のコードのように外部からアクセスすることもできます。

>>> if True:
...  msg = 'I am from demo'
... 
>>> msg
'I am from demo'
>>> 

インスタンス内の msg 変数は if ステートメント ブロック内で定義されていますが、外部からアクセスすることもできます。

msg が関数内で定義されている場合、それはローカル変数であり、外部からアクセスすることはできません。

>>> def test():
...     msg_inner = 'I am from demo'
... 
>>> msg_inner
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'msg_inner' is not defined
>>> 

エラー メッセージから、msg_inner は未​​定義であり、ローカル変数であり関数内でのみ使用できるため、使用できないことがわかります。

グローバル変数とローカル変数

関数内で定義された変数にはローカル スコープがあり、関数の外で定義された変数にはグローバル スコープがあります。

ローカル変数は宣言されている関数内でのみアクセスできますが、グローバル変数はプログラム全体からアクセスできます。関数が呼び出されると、関数内で宣言されたすべての変数名がスコープに追加されます。例は次のとおりです。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
total = 0 # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
    #返回2个参数的和."
    total = arg1 + arg2 # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)
    return total
 
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)

上記の例の出力は次のとおりです。

函数内是局部变量 :  30
函数外是全局变量 :  0

グローバルキーワードと非ローカルキーワード

内部スコープが外部スコープの変数を変更する場合は、global キーワードと nonlocal キーワードが使用されます。

次の例では、グローバル変数 num を変更します。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
num = 1
def fun1():
    global num  # 需要使用 global 关键字声明
    print(num) 
    num = 123
    print(num)
fun1()
print(num)

上記の例の出力は次のとおりです。

1
123
123

ネストされたスコープ (外側のスコープ、外側の非グローバル スコープ) 内の変数を変更する場合は、次の例に示すように、nonlocal キーワードが必要です。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
def outer():
    num = 10
    def inner():
        nonlocal num   # nonlocal关键字声明
        num = 100
        print(num)
    inner()
    print(num)
outer()

上記の例の出力は次のとおりです。

100
100

さらに、特殊なケースとして、次のコードが実行されるとします。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
a = 10
def test():
    a = a + 1
    print(a)
test()

上記のプログラムを実行すると、次のようなエラーメッセージが表示されます。

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    test()
  File "test.py", line 5, in test
    a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment

テスト関数内の a はローカルの未定義の値を使用しており、変更できないため、このエラー メッセージはローカル スコープ参照エラーです。

a をグローバル変数に変更します。

#!/usr/bin/python3
 
a = 10
def test():
    global a
    a = a + 1
    print(a)
test()

実行出力は次のとおりです。

11

関数パラメータとして渡すこともできます。

例 (Python 3.0 以降)

#!/usr/bin/python3
 
a = 10
def test(a):
    a = a + 1
    print(a)
test(a)

実行出力は次のとおりです。

11

おすすめ

転載: blog.csdn.net/u011397981/article/details/131100793
おすすめ