2016-12-02 6 views
1

私はPython 3.xデータモデルをよりよく理解したいと思います。しかし、私はPython Objectの振る舞いを完全かつ正確に説明していません。Pythonオブジェクトメカニズムの深い理解

私は参考文献を探していますが、下に示すすべてのケースをPython APIリファレンスやPEPなどの貴重なものにリンクさせることができれば嬉しいです。あなたは賢明な助言のためにさらにいただきありがとうございます...

みましょう、我々はテスト目的のためにいくつかの複雑なPythonの構造を持っていると言う:

d1 = { 
    'id': 5432 
    ,'name': 'jlandercy' 
    ,'pets': { 
     'andy': { 
      'type': 'cat' 
      ,'age': 3.5 
     } 
     ,'ray': { 
      'type': 'dog' 
      ,'age': 6.5 
     } 
    } 
    ,'type': str 
    ,'complex': (5432, 6.5, 'cat', str) 
    ,'list': ['milk', 'chocolate', 'butter'] 
} 

1)不変原子オブジェクトは

どのような方法でシングルトンです私は新しい整数を作成します。

n1 = 5432 
n2 = int(5432) 
n3 = copy.copy(n1) 
n4 = copy.deepcopy(n1) 

この番号の新しいコピーは作成されず、代わりに新しいものが作成されますオブジェクトはd1['id']です。もっと簡潔に

d1['id'] is n1 
... 

彼らはすべて同じidを持っていない、従って私はそれがシングルトンで、値が5432でintの新しいインスタンスを作成することはできません。

2)不変と反復処理可能なオブジェクトはシングルトンであるかもしれない...

前の観測も不変反復可能である、strのために働きます。以下のすべての変数:

s1 = 'jlandercy' 
s2 = str('jlandercy') 
s3 = copy.copy(s1) 
s4 = copy.deepcopy(s1) 

最初に作成されたコピー先はd1['name']です。文字列もシングルトンです。

...ではなく、正確に...

タプルも不変と反復可能ですが、彼らは、文字列のように動作しません。

() is() 

しかし、他のタプルではない:魔法の空のタプルがシングルトンであることを知っています。

t1 = (5432, 6.5, 'cat', str) 

...代わりに、彼らは同じように

をハッシュ彼らは同じidを持っていない:

id(d1['complex']) != id(t1) 

しかし、これら二つの構造内のすべての項目はアトミックなので、同じ方向にポイントインスタンス。

hash(d1['complex']) == hash(t1) 

そこで彼らは、辞書のキーとして使用することができます。重要な点は、両方の構造hash同じ方法です。これはネストされたタプルでも当てはまります。

t2 = (1, (2, 3)) 
t3 = (1, (2, 3)) 

これらは同じhashを持っています。二重の間接参照によって辞書を渡す

3)は、それのようシャローコピー

は、次の関数を定義できます動作します。

最初の二重間接参照(**オペレータ)によって、当社のトライアル辞書を受け取ります
def f1(**kwargs): 
    kwargs['id'] = 1111 
    kwargs['pets']['andy'] = None 

学位会員はコピーされますが、最も深いものは参考にされます。この単純なプログラムの

出力は、それを示しています

{'complex': (5432, 6.5, 'cat', <class 'str'>), 
'id': 5432, 
'list': ['milk', 'chocolate', 'butter'], 
'name': 'jlandercy', 
'pets': {'andy': {'age': 3.5, 'type': 'cat'}, 
      'ray': {'age': 6.5, 'type': 'dog'}}, 
'type': <class 'str'>} 

{'complex': (5432, 6.5, 'cat', <class 'str'>), 
'id': 5432, 
'list': ['milk', 'chocolate', 'butter'], 
'name': 'jlandercy', 
'pets': {'andy': None, 'ray': {'age': 6.5, 'type': 'dog'}}, 
'type': <class 'str'>} 

辞書d1が機能f1によって変更された、完全ではない:

print(d1) 
f1(**d1) 
print(d1) 

それを返します。メンバーid 'はコピーを作成したので元に戻りますが、メンバーpetsも辞書であり、浅いコピーはそれをコピーせずに変更されました。

この動作は、dictオブジェクトのcopy.copyの動作に似ています。オブジェクトの再帰的かつ完全なコピーを持つにはcopy.deepcopyが必要です。

私の要求は、次のとおりです。

  • は私の観測が正しく解釈されていますか?

    1. 不変原子オブジェクトは

    2. 不変と反復処理可能なオブジェクトはシングルトンであるかもしれないではなく、まさにその代わり、彼らは二重の間接参照によって辞書を渡す均等

    3. はそれ

    4. の浅いコピーを作品ハッシュシングルトンです
  • これらの動作はどこかで十分に文書化されていますか?
  • それぞれのケースについて正しいプロパティ&ビヘイビアを示します。

答えて

1

不変アトミックオブジェクトはシングルトン

いいえ、一部であり、一部ではない、これはCPythonの実装の詳細です。範囲(-6, 256]

  • 整数はキャッシュされ、これらのための新しい要求が行われたときに、既存のオブジェクトが返されます。その範囲外の数値は、一定の折り畳みの対象となります。ここで、インタプリタは、コンパイル時に定数をわずかな最適化として再利用します。新しいPyLongオブジェクトを作成するセクションのThis is documentedを参照してください。

    はまた、これらの議論については以下を参照してください。

  • 文字列リテラルはint型がそうであるようにバイトコードにコンパイル時にインターンの対象となっています。しかし、これを支配するための規則は、intの場合と同じくらい単純なものではありません。特定の文字で構成される特定のサイズの文字列のみが考慮されます。私はこれを指定しているドキュメントのセクションを認識していません。あなたはhereを読んで振る舞いを見ることができます。 (この用語は、あなたが考える意味を持っていないことをPythonでも)「アトミック」と考えることができる例えば

  • フロート、何のシングルトンはありません。

    i = 1.0 
    j = 1.0 
    i is j # False 
    

    彼らはもちろん、まだあります絶えず折り畳まれている。あなたが読書で見ることができるように:'is' operator behaves unexpectedly with floats

不変と反復処理可能なオブジェクトはシングルトンかもしれないが、正確に代わり、彼らは同様に

コレクションはsignletonsある空immutablesをハッシュません。これはやはりPythonリファレンスでは見つけられない実装の詳細ですが、ソースを見ると実際にしか発見されません。

は、実装を見についてはこちらをご覧ください:ダブル間接参照によって辞書を渡すWhy does '() is()' return True when '[] is []' and '{} is {}' return False?

はそれのように浅いコピーを動作します。

はい。この用語は二重逆参照ではありませんが、アンパックしています。

これらの動作はどこかで十分に文書化されていますか?

実装の詳細と考えられるものは、たとえばmax関数のドキュメントを見つける方法で文書化する必要はありません。これらは決定がなされた場合に容易に変わるかもしれない特定のものです。

+0

あなたの答えはかなり完成しています。他のポップアップがあればもう少しお待ちしております。とにかくありがとうございました。 – jlandercy

+0

それはsenceを@jlandercyにして、あなたが思うように多くの時間を与えます:-) –

+0

[2]でハッシュに情報を追加できますか?不変でiterable(stdlibのみ)のハッシュは常に同じ方法ですか?たとえば、私はnamed_tupleまたはタプル "原子型"を使用する必要がありますか?ありがとう – jlandercy

関連する問題