Pythonにおける役割ドメインおよびglobal用法

4161 ワード

Pythonでは,1つの変数の役割ドメインは常にコードに付与された場所によって決定される.
  • 関数はローカル役割ドメインを定義し、モジュールはグローバル役割ドメインを定義します.関数内でグローバル役割ドメインを定義するにはglobal修飾子を付ける必要があります.
  • 変数名解析:LEGB原則関数に未認証の変数名を使用する場合、Pythonは4つの役割ドメイン[ローカル役割ドメイン(L)(関数内部宣言はglobalを使用していない変数)を検索し、その後は前の階層のdefまたはlambdaのローカル役割ドメイン(E)であり、その後はグローバル役割ドメイン(G)(関数でglobalを使用して宣言された変数またはモジュール層で宣言された変数)であり、最後に内蔵役割ドメイン(B)である(pythonの内蔵クラスや関数など)を最初に見つけることができる場所で停止します.変数名が検索中に見つからなかった場合、Pythonはエラーを報告します.補足:上の変数ルールは単純なオブジェクトにのみ適用され、引用オブジェクトの属性が現れた場合、別の検索ルールがあります.属性参照は1つ以上のペアを検索します.役割ドメインではなく、いわゆる「継承」にかかわる可能性があります.
  • 以上http://blog.csdn.net/carolzhang8406/article/details/6855525

  • global修飾子を検討する前に、Pythonデータ型を理解する必要があります.Python 3には6つの標準的なデータ型があります.
  • Number(数値)
  • String(文字列)
  • List(リスト)
  • Tuple(タプル)
  • Set(集合)
  • Dictionary(辞書)
  • Python 3の6つの標準データ型のうち:
  • 可変データ(3個):Number(数字)、String(文字列)、Tuple(タプル)、
  • 可変データ(3個):List(リスト)、Dictionary(辞書)、Set(セット).
  • データ型の可変および非可変については、次の定義があります.
    可変データ型:データ型の対応する変数の値が変更されると、対応するメモリアドレスも変更されます.このデータ型については、可変データ型と呼ばれます.≪可変データ型|Variable Data Type|emdw≫:データ型の対応する変数の値が変更されると、対応するメモリ・アドレスは変更されません.このデータ型を可変データ型と呼びます.まとめ:可変データ型変更後にアドレスが変更され、可変データ型変更アドレスは変更されません.
    global修飾子の使い方を検討します.
    1.可変データ型
    ここではString(文字列)タイプを例に分析します.
  • はまずpythondの奇異な現象であり、モジュールレベルで定義された変数(global修飾を必要としない)は、関数に同名の変数が定義されていない場合、関数でグローバル変数として使用することができる:
    mess = 'hello'
    
    def foostr():
        # global mess
        print('         :{}'.format(id(mess)))
    
    foostr()
    print('         :{}'.format(id(mess)))
    print(mess)
    
    出力結果:
             :2559622609304
             :2559622609304
    hello
    
    コードでglobalの注釈をキャンセルし、出力された変数アドレスは依然として一致している.
  • 関数に再割り当て/定義がある場合(pythonは弱い言語であるため、付与文は変数を定義する文と同じである).
    mess = 'hello'
    
    def foostr():
        # global mess
        mess = 'world'
        print('         :{}'.format(id(mess)))
    
    foostr()
    print('         :{}'.format(id(mess)))
    print(mess)
    
    の出力結果は、
             :1821595892736
             :1821595892120
    hello
    
    のコードが正常に動作し、helloとして出力され、所望のworld結果が得られなかった.LEGBの原則分析によると、モジュールに宣言されたmess変数のメモリ内のアドレスと、関数内で宣言されたmess変数メモリアドレスが違います.
  • 関数で変数を使用した後に変更できる場合(すなわち再付与、注意が必要なのは、ここでのデータ型は可変ではないので、すべての修正は再付与操作である)どのように関数に使用される変数がモジュール層で定義されたそのグローバル変数であって関数内部の局所変数ではないようにするのか.このときglobal修飾子が役に立つ.
    mess = 'hello'
    
    def foostr():
        global mess
        mess = 'world'
        print('         :{}'.format(id(mess)))
    
    foostr()
    print('         :{}'.format(id(mess)))
    print(mess)
    
             :1747608435656
             :1747608435656
    world
    
    global修飾子で音声を修飾する明messはグローバル変数のmess後(global文ではglobal mess=‘world’のような同時付与は許されないことに注意)、上記出力はworldであり、我々が望む効果を得た.
  • 2.可変データ型
    ここではDictionary(辞書)を例に分析する.
    モジュールレベルで定義された変数(global修飾を必要としない)は、関数に同じ名前の変数が定義されていない場合は、関数でグローバル変数として使用でき、直接コンテンツの変更を行うことができます.
    c = {}
    
    def foo():
        # global c
        c['a'] = 1
        print('         :{}'.format(id(c)))
    
    print(c)
    foo()
    print('         :{}'.format(id(c)))
    print(c)
    

    出力結果は次のとおりです.
    {}
             :2231654522816
             :2231654522816
    {'a': 1}
    

    テスト中、globalのコメントをキャンセルするかどうかにかかわらず、結果の変数のメモリ内のアドレスは一致します.なぜなら,我々が関数内部で行ったのは再付与操作ではなく,元の辞書オブジェクトで行った修正操作であり,「=」付与操作ではなくgolbal宣言を用いなくてもよいからである.
    c = {}
    
    def foo():
        # global c
        c = {'a':1}
        print('         :{}'.format(id(c)))
    
    print(c)
    foo()
    print('         :{}'.format(id(c)))
    print(c)
    

    出力結果は次のとおりです.
    {}
             :2388490697608
             :2388490624888
    {}
    

    globalを使用して宣言していない場合、辞書オブジェクトは関数で変更されていないことがわかります.関数で再宣言された辞書オブジェクトcは新しいものであり、この変数はローカルの役割ドメインのみであるからです.グローバル役割ドメインの変数cではありません.
    深く分析するとpythonは弱いタイプの言語で、付与文は変数を定義する文と同じであるため、c={‘a’:1}という文では、グローバル変数cを参照することも、新しいローカル変数を作成することもできるため、pythonではglobalを明示的に宣言しない限り、global定義のローカル変数がグローバル変数に対応する別名、すなわち同じ変数になる場合を除き、デフォルトの動作はローカル変数を作成することです.
    まとめ:グローバル変数が数値、文字列、メタグループなどの可変データ型である場合、関数が割り当てを再定義するときにglobalで宣言します.グローバル変数がリスト、コレクション、辞書のような可変タイプである場合、listまたはdictの内蔵関数を使用して関数内部を変更する場合はglobal宣言を使用しなくてもよい」