ソースコードの歩き方《IronPython》dict.Items
Python.use(better, src=”IronPython”) # ソースコードを散策する《記事一覧》
メソッド:dict.items
メソッド items は、写像対の集合に相当します。
>>> help(dict.items)
Help on method_descriptor:items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
これを見て、2つの要素を持つタプル(キー, 値)を列挙したリストが得られるのが分かります。実際に、その動作を確認してみましょう。
>>> ex
{'A': 1, 'C': 3, 'B': 2}
>>> ex.items()
[('A', 1), ('C', 3), ('B', 2)]
ここでは、2つの要素を持つタプル(文字列, 整数)を列挙したリストが得られます。ただし、タプルは重複せずに、順不同となります。
ソースコード:items()
(メソッド dict.items に相当する)メソッド items の定義を含む、ソースコードの断片を次に示します。
# IronPython-1.1.2/Src/IronPython/Runtime/Dict.cs
[PythonType("dict")]
public class Dict : ... IDictionary
メソッド Items では、メソッド DictOps.Items の実引数に、this を指定しています。これは、内部クラス DictOps ですべての操作を実現しているので、それに自身 this の処理を委ねるためです。このとき(Dict のインスタンス)this は、インターフェース IDictionary の規定に従うものとします。さらに、IDictionary を構成する各要素は、ジェネリック構造体 KeyValuePair の規定に従うものとします。
《参照》ジェネリック構造体 KeyValuePair:詳細は、http://msdn.microsoft.com/ja-jp/library/5tbh8a42.aspx を参照してください。
internal static class DictOps {
...
public static List Items(IDictionary
静的メソッド Items では、変数 ret がリターン値を扱うために、空の(必要な領域を確保した)リスト List を保持します。すると、次のような構造が見えてきます。
List ret = ... self.Count ... // IDictionary.Count
...
return ret;
プロパティー IDictionary.Count を利用しているのが分かります。
ここでは、どのようにしてリストが得られるか(how)は知らなくても、それを使ってなにをしたいか(what)を理解できれば、十分です。self.Count 個の要素を保持するリストが欲しいときに、List.MakeEmptyList を利用するだけです。
foreach 文
ここには、次に示す典型的な C# のイディオムが記述してあります。
foreach (... kv in self) {
... kv ...
}
foreach ループでは、IDictionary self を構成する各要素 KeyValuePair kv を順に参照します。
ret.AddNoLock(Tuple.MakeTuple(
kv.Key, // KeyValuePair.Key
kv.Value)); // KeyValuePair.Value
各要素 kv をもとに生成したタプルを、リスト ret に追加します。
ここでは、どのようにしてタプルが得られるか(how)は知らなくても、それを使ってなにをしたいか(what)を理解できれば、十分です。2つの要素(kv.Key, kv.Value)を持つタプルが欲しいときに、Tuple.MakeTuple を利用するだけです。
事例:dict.items を使って
>>> dirs = dict([(e,type(getattr(dict,e))) for e in dir(dict)])
>>> for k,v in dirs.items():
... if k in ["keys","values","items"]: print k,v
...
keys
items
values
これらはどれも、method_descriptor であるのが分かります。
《ひよ子のきもち♪2008/08/22》