python 3における各種変数のメモリスタック割り当てと関数パラメータの違いの例の詳細


メモリの効率的な利用は、プログラムの作成過程における昔から変わらない話題であり、python 3の様々な変数のメモリ使用の違いと、関数の参照を行う際の注意点を実際の操作で見てみましょう.
文書ディレクトリ
  • メモリ内のスタック
  • 異なるデータ型メモリ使用
  • 可変オブジェクト
  • 小整数と大整数
  • 短い文字列と長い文字列
  • 浮動小数点数
  • タプル
  • ブール値
  • 可変オブジェクト
  • 匿名オブジェクト
  • 変数名付与変数
  • 関数パラメータ
  • まとめ
  • メモリ内のスタック
    動的言語であるため、pythonのすべての変数コンテンツはスタック(heap)に存在し、変数名はスタック内のコンテンツの参照にすぎず、スタック(stack)に格納され、スタック内のデータを間接的に操作するのに便利である.これは関数パラメータの伝達を後で理解するのに非常に重要である.
    対照的にjavascriptを例にとると、数値、文字列、ブール値などの基本データ型がスタック内に直接存在する.複合データ型、例えばarray、objectは、スタック内に存在し、スタック内にはスタックアドレスの参照が格納される
    しかしスタック内の変数名とスタック内の実際の内容は一対一の関係ではなく,変数タイプや具体的な内容と関係がある.次に具体例を用いて順次実験を行う.
    異なるデータ型メモリの使用
    まず、id()コマンドは、スタック内の変数のメモリアドレスを表示するために使用でき、同時に==は2つの変数値のサイズを比較するためにのみ使用でき、isはメモリアドレスと値を同時に比較することができることを理解する必要があります.
    可変オブジェクト
    pythonの可変オブジェクトは、次のとおりです.
  • int
  • float
  • bool
  • tuple
  • string

  • この5種類を可変オブジェクトと呼ぶのは,変数名とスタック内のあるアドレスがバインドされた後,その変数の値を変更しようとすると,その変数名と別のスタックアドレスが再バインドされるからである.言い換えれば、5種類の可変オブジェクトについて、変数の値が異なる場合、メモリアドレスは必ず異なる.同じ変数で内容を変更した後、メモリアドレスが一定に変更されます.しかし、異なる変数に対してそれぞれ同じ内容を付与し、2つの変数がスタック内で対応するアドレスは必ず同じであるのではないでしょうか.これは必ずしもそうではありません.次は順番に見てみましょう.
    小さい整数と大きい整数
    pythonでは、-5~256の小さな整数をスタックに独立したキャッシュ領域を割り当てます.つまり、変数がこれらの値を参照する場合、値が同じであれば、メモリアドレスが何回参照されても同じです.また、別の区間の整数では、値が同じであっても、複数回参照すると異なるメモリアドレスが作成されます.
    In [1]: int1=1                                                                                                                                                               
    
    In [2]: int2=1                                                                                                                                                               
    
    In [3]: id(int1)                                                                                                                                                             
    Out[3]: 94569156809600
    
    In [4]: id(int2)                                                                                                                                                             
    Out[4]: 94569156809600
    
    In [5]: int3=123456                                                                                                                                                          
    
    In [6]: int4=123456                                                                                                                                                          
    
    In [7]: id(int3)                                                                                                                                                             
    Out[7]: 140692865269264
    
    In [8]: id(int4)                                                                                                                                                             
    Out[8]: 140692864485680
    

    したがって、大きな整数では、値が同じであっても、呼び出しメモリアドレスによって異なります.
    短い文字列と長い文字列
    pythonでは、スペースのない文字列を短い文字列として認定し、内容が同じであれば、何度アドレスを参照しても同じです.スペースが入っているのは、同じ内容でも複数回引用するアドレスが違います
    In [1]: str1='dfkdjf'                                                                                                                                                        
    
    In [2]: str2='dfkdjf'                                                                                                                                                        
    
    In [3]: id(str1)                                                                                                                                                             
    Out[3]: 140645071595648
    
    In [4]: id(str2)                                                                                                                                                             
    Out[4]: 140645071595648
    
    In [5]: str3='dfkdjf rrr'                                                                                                                                                    
    
    In [6]: str4='dfkdjf rrr'                                                                                                                                                    
    
    In [7]: id(str3)                                                                                                                                                             
    Out[7]: 140645018745904
    
    In [8]: id(str4)                                                                                                                                                             
    Out[8]: 140645018373744
    

    中国語であれば、スペースがあるかどうかにかかわらず、住所が違いますので注意してください.
    In [9]: str5='    '                                                                                                                                                      
    
    In [10]: str6='    '                                                                                                                                                     
    
    In [11]: id(str5)                                                                                                                                                            
    Out[11]: 140645017829736
    
    In [12]: id(str6)                                                                                                                                                            
    Out[12]: 140645017830568
    

    したがって、長い文字列では、値が同じであっても、呼び出しメモリアドレスによって異なります.
    浮動小数点数
    浮動小数点数には短さの区別はなく、参照先によって必ず異なる
    In [1]: f1=1.23                                                                                                                                                              
    
    In [2]: f2=1.23                                                                                                                                                              
    
    In [3]: id(f1)                                                                                                                                                               
    Out[3]: 139760803510072
    
    In [4]: id(f2)                                                                                                                                                               
    Out[4]: 139760803510144
    

    メタグループ
    メタグループは浮動小数点型と同様にアドレスが異なります
    In [5]: tup1=(1,2,3)                                                                                                                                                         
    
    In [6]: tup2=(1,2,3)                                                                                                                                                         
    
    In [7]: id(tup1)                                                                                                                                                             
    Out[7]: 139760792784472
    
    In [8]: id(tup2)                                                                                                                                                             
    Out[8]: 139760801764336
    

    ブール値
    ブール値は全部で2つなので、メモリ内の同じ値のアドレスは変わりません.
    In [9]: b1=True                                                                                                                                                              
    
    In [10]: b2=True                                                                                                                                                             
    
    In [11]: id(b1)                                                                                                                                                              
    Out[11]: 94256849978176
    
    In [12]: id(b2)                                                                                                                                                              
    Out[12]: 94256849978176
    

    可変オブジェクト
    pythonの可変オブジェクトは、次のとおりです.
  • list
  • dict
  • set

  • 可変オブジェクトであるのは,1つの変数がスタック内のアドレスにバインドされると,変数の内容が変更されてもスタック内のアドレスは変わらないからである.したがって,3種類の可変オブジェクトについては,値が同じかどうかにかかわらず,異なる変数に対応するメモリアドレスは一定に異なるが,同じ変数に対応するメモリアドレスは一定に変わらない.
    以下のように、値が同じであってもメモリアドレスが異なる
    In [13]: set1={1,2,3}                                                                                                                                                        
    
    In [14]: set2={1,2,3}                                                                                                                                                        
    
    In [15]: id(set1)                                                                                                                                                            
    Out[15]: 139760793306952
    
    In [16]: id(set2)                                                                                                                                                            
    Out[16]: 139760793308520
    
    In [17]: dic1={}                                                                                                                                                             
    
    In [18]: dic2={}                                                                                                                                                             
    
    In [19]: id(dic1)                                                                                                                                                            
    Out[19]: 139760801165384
    
    In [20]: id(dic2)                                                                                                                                                            
    Out[20]: 139760800828368                                                                                                                                                       
    
    In [22]: list1=[1,2]                                                                                                                                                         
    
    In [23]: list2=[1,2]                                                                                                                                                         
    
    In [24]: id(list1)                                                                                                                                                           
    Out[24]: 139760801034760
    
    In [25]: id(list2)                                                                                                                                                           
    Out[25]: 139760800576904
    

    同じ変数でも、内容が変更されてもメモリアドレスは変更されません.
    In [1]: list1=[1,2]                                                                                                                                                          
    
    In [2]: id(list1)                                                                                                                                                            
    Out[2]: 139780650584328
    
    In [3]: list1.append(3)                                                                                                                                                      
    
    In [4]: id(list1)                                                                                                                                                            
    Out[4]: 139780650584328
    

    以上のすべての例を総合すると,以下にまとめることができる.
  • 実際のデータはすべてスタックに格納され、スタック内の変数はすべてスタック内のデータの参照
  • に格納されます.
  • 可変オブジェクトの小さな整数、短い文字列、およびブール値は、値が同じメモリアドレスであれば同じです.残りのタイプは、値が同じかどうかにかかわらず、メモリアドレスが異なります
  • 可変オブジェクトは、単一の変数に対して値がどのように変化してもメモリアドレスが固定されます.しかし、異なる変数は、値が同じかどうかにかかわらず、メモリアドレスが異なる
  • 匿名オブジェクト
    しかし、特に以下に説明するのは数値を直接使う場合で、比較的幻想的です.
    In [14]: id([1,2])                                                                                                                                                           
    Out[14]: 139780420063624
    
    In [15]: id([3,4])                                                                                                                                                           
    Out[15]: 139780677582280
    
    In [16]: id([1,2])==id([3,4])                                                                                                                                                
    Out[16]: True
    

    pythonは匿名可変オブジェクトのためにスタックに統一されたメモリアドレスを開いているため、露出したアドレスは一致しているという.ここでは詳しく考えませんが、メモリアドレスを見る可能性はあまりありません.
    変数名を変数に割り当てる
    pythonの変数がスタック内のデータのアドレスで格納されている以上、ポインタに似ているので、変数名を別の変数に割り当てるのは、新しい変数を同じメモリアドレスに指すことに相当します.値を変更した後の2つの変数の値をどのように変更するかは、上記のデータ型のメモリアドレス変換法則に基づいて押すだけでよい.
    いくつか例を挙げる.
    可変オブジェクトの整数
    In [17]: a=123                                                                                                                                                               
    
    In [18]: b=a                                                                                                                                                                 
    
    In [19]: id(a)                                                                                                                                                               
    Out[19]: 94805275202240
    
    In [20]: id(b)                                                                                                                                                               
    Out[20]: 94805275202240
    
    In [21]: b                                                                                                                                                                   
    Out[21]: 123
    

    ここで変数abは同じアドレスを指し、その後aの値を変更する.
    In [22]: a+=1                                                                                                                                                                
    
    In [23]: id(a)                                                                                                                                                               
    Out[23]: 94805275202272
    
    In [24]: id(b)                                                                                                                                                               
    Out[24]: 94805275202240
    

    したがって、変数aの値は変化し、bの値は変わらない.
    In [25]: a                                                                                                                                                                   
    Out[25]: 124
    
    In [26]: b                                                                                                                                                                   
    Out[26]: 123
    

    可変オブジェクトのリスト
    In [27]: c=[1,2,3]                                                                                                                                                           
    
    In [28]: d=c                                                                                                                                                                 
    
    In [29]: id(c)                                                                                                                                                               
    Out[29]: 139780440014600
    
    In [30]: id(d)                                                                                                                                                               
    Out[30]: 139780440014600
    

    その後、cの内容を修正し、上記の法則に従ってcのアドレスは変更されず、ソースアドレスを指すため、cdの値は変更された.
    In [31]: c.append(4)                                                                                                                                                         
    
    In [32]: id(c)                                                                                                                                                               
    Out[32]: 139780440014600
    
    In [33]: id(d)                                                                                                                                                               
    Out[33]: 139780440014600
    
    In [34]: c                                                                                                                                                                   
    Out[34]: [1, 2, 3, 4]
    
    In [35]: d                                                                                                                                                                   
    Out[35]: [1, 2, 3, 4]
    

    かんすうパラメータ
    上記の変数名付与値を理解してから,関数パラメータを見ると簡単である.パラメータはスタック内の変数の内容を関数内に渡すことであり、ポインタを関数内に渡すことに相当するため、関数内の変数に対する操作も可変オブジェクトと可変オブジェクトの2つに分けられる.
    可変オブジェクトが渡されている場合、関数内で変更する必要があるのは、変数を別のアドレスに指すだけなので、関数外の変数の内容には影響しません.可変オブジェクトとして渡された場合、関数内で変更するか元のアドレスで変更するかは、関数外の変数の内容にも影響します.
    補足:javascriptを比較すると、jsの基礎変数はすべて値をスタック内に直接保存するので、関数に値を渡すことに相当し、関数内の操作は関数外の変数値に影響しません.jsの複合変数も同様に値をスタック内に保存するので,伝達ポインタに相当し,関数内の操作も関数外の変数値に影響する.
    まとめ
    知識点をまとめる
  • 実際のデータはすべてスタックに格納され、スタック内の変数はすべてスタック内のデータの参照
  • に格納されます.
  • 可変オブジェクトの小さな整数、短い文字列、およびブール値は、値が同じメモリアドレスであれば同じです.残りのタイプは、値が同じかどうかにかかわらず、メモリアドレスが異なります
  • 可変オブジェクトは、単一の変数に対して値がどのように変化してもメモリアドレスが固定されます.しかし、異なる変数は、値が同じかどうかにかかわらず、メモリアドレスが異なる
  • パラメータを渡すときはすべてポインタで、修正内容によってメモリアドレスを変更するかどうかによって外部変数に影響するかどうかを見て、可変オブジェクトは影響しないで、可変オブジェクトは影響します
  • を比較するjavascript、基礎変数は伝値で、関数内の修正は外部変数に影響しない、複合変数は伝針で、関数内の修正は外部変数に影響する
  • 私はT型の人です.一生勉強するインターネット業者です.私のブログが好きでcsdnの上で私に関心を持つことを歓迎して、もし問題があれば下の評論区で交流することを歓迎して、ありがとうございます.