2011-08-03 6 views
8

なぜPythonのinternは文字列専用ですか? internをハッシュ可能で同等のクラスに拡張することは可能でしょうか?非文字列用のPythonインターン

+1

不変オブジェクトのために 'intern'のようなオブジェクトキャッシュを作成することができます。 –

+0

@Peter:そうです。 'intern'の利点は、そのためのコードはすべて自動的に生成され、ボーナスとしては高速なC++であることです。 –

+2

@NeilG私はそうは思わない。 AFAIK CPythonはC++ではなく完全にCで書かれています。 – glglgl

答えて

14

物をインターンにする目的は、メモリアドレスを比較することによってそれらを比較できるようにすることです。同じ値を持つ2つのオブジェクトを決して作成しないようにします(プログラムが既存のオブジェクトと同じ値を持つ2番目のオブジェクトの作成を要求した場合、代わりに既存のオブジェクトへの参照を受け取ります)。これは、あなたが中止しているものが不変であることが必要です;インターンされたオブジェクトの値が変更される可能性がある場合、それらをアドレスで比較することは機能しません。

Pythonでは、ユーザ定義のクラスインスタンスの不変性を強制することはできないため、それらを中断することは安全ではありません。私はそれが、クラスのインスタンスをカバーしていない主な理論上の理由であると考えています。

不変タイプに内蔵された他は、すでに(整数、フロート、など)単一のマシンレベルの動作に匹敵する、またはが可変値(タプル、frozensetの)を含むことができる不変コンテナのいずれかです。前者をインターンにする必要はなく、後者を安全に拘禁することはできません。

+0

+1。 「Pythonでは、ユーザ定義のクラスインスタンスの不変性を強制することはできません。どれほど残念ですか? – ShreevatsaR

0

インターンはポインタベースのobject identity testに依存しているため、文字列のみがサポートされています。他のタイプのクラスのハッシュを比較することはできますが、オブジェクト自体はアイデンティティテストと決して一致しません。これは同じでも同じオブジェクトではないため、当てはまります。

Reference

+3

私が理解しているように、ポインタベースのオブジェクト同一性テストは、インターンで得られる利点であり、インターンのものに必要なものではありません。インターンのオブジェクトに依頼している場合、同じ価値を持つ2人のうち、同じ価値を持つものを本来持っていると考えています(Neil Gは、「ハッシュ可能で類似」と言います)。そのためには、それらが不変であることが必要です。これは、Pythonのクラスインスタンスの実行可能なプロパティではありません。私はそれがサポートされていない主な理論上の理由だと思います。 – Ben

+0

@Ben:それは私の質問の良い解釈です。また、あなたの最後のポイントはおそらくこの質問の答えです。お気軽に回答を追加してください。 –

1

言う、私は現実の世界で、これは文字列リテラルに比べてほとんど価値があることを想像するだろうけれどもタプルは、インターンすることができませんでしたし、それもであろう、という技術的な理由はありませんユーザー定義の型では現実的でない価値があります。おそらく努力する価値があるとは考えられないでしょう。

+5

タプルの内容は変更可能です。インターリングするタプルは奇妙な動作を引き起こす可能性があります。例えば。 'a、b =([])、([]); a [0] .append( 'foo') 'は、' a'と 'b'がタプル内部実装に依存する異なるタプルであるかどうかによって異なる結果を持つでしょう。どうやら、Fortranのいくつかの実装は[何か類似していました](http://stackoverflow.com/questions/1995113/strangest-language-feature/1995476#1995476)。 –

+2

@Peter:インターナショナルという考えは、あなたが説明したような副作用がない場合にのみ行うことができます。タプルをインターンすることは、明らかに、すべての要素が単に同じではなく、すでにインターンされているタプルと同じオブジェクトであることを確認する必要があります。実際に要素を最初にインターンしようとする可能性があります(これは、数値型も内部に入れられると便利です)。あなたの例では、同じリストを含んでいなければ、タプルは単に参照を共有することができません。 Pythonをすべて修正することができなかった技術的な理由はありません。 – kindall