Javascriptのような辞書オブジェクトの実装

最近、私の脳とJavascriptの長い相互作用の後、私はいつものPythonに戻り、何か、つまりJavascriptのようなオブジェクト、ハッシュテーブルを持っているオブジェクトが欠けていることに気付きました。 Fuuuuu、多分あなたは言う、そしておそらく無駄に。

もっと明確に言えば、私は本格的なPython dictが欲しいと思っていましたが、それはオブジェクトの属性としてその値にアクセスできるようにするためだけです。 個人的にはa["name"]代わりにa.nameを書くa.nameがずっといいです:

>>> a。 id = 42
>>> a。 name = "Jon"
>>> 印刷
{ 'id'42'name''Jon' }


この場合、もちろん、標準の辞書機能を維持することが重要です。

>>> print "id:%(id)d、name:%(name)s" a
id42 、名前:ジョン
>>> a。 キー
[ 'id''name' ]


いいね では、Python自体でそれを行わないのはなぜですか?

実装1.額に。


最初に頭に浮かぶのは、必要なすべての魔法のメソッドの作業を実装することです。

クラス Dict dict
def __getattr__ self 、key
自己を 返す [キー]
def __setattr__ self 、key、value
自己 [キー] =値
def __delattr__ self 、key
del self [ key ]


しかし、それはあまりにもPythonicではないようです。 少し詳しく見ると、余分な作業が行われていることがわかり、コードを削減できます。

実装2. Pythonのタオ。


実際、同じシグネチャを持つため、バインドされていないメソッドを他のメソッドに置き換えるだけで十分です。

クラス Dict dict
__getattr__ = dict__getitem__
__setattr__ = dict__setitem__
__delattr__ = dict__delitem__


それは確かに良く見えますが、とにかく不器用で拡張性がありません。 この考えで夜寝ていたのに、朝になって、おそらく最もエレガントな解決策になりました。

実装3.小さな魔法。


クラス Dict dict
def __new__ cls、 * args、 ** kwargs
self = dict__new__ cls、 * args、 ** kwargs
自己__dict__ = self
戻ります


何が起こっているのか理解していますか? 最も興味深いのは、 self.__dict__ = selfという行です。 実際、私たちのオブジェクトは普通の辞書ですが、なぜ自分の属性の辞書でもないのですか? これで、Dictクラスのインスタンスの属性を取得、変更、または削除すると、これらの変更は、辞書としてのこのインスタンスの値に直接影響します。本質的に、これらは同じエンティティになっているためです。

>>> d = Dict a = 1 、b = 2 、c = 3
>>> 印刷 d
{ 'a'1'c'3'b'2 }
>>> 印刷 d。 a == d [ "a" ]
本当
>>> d。 b = 7
>>> del d。 c
>>> d。 x = 4
>>> 印刷 d
{ 'a'1'x'4'b'7 }
>>> 印刷 d。 キー 、d。 アイテム
[ 'a''x''b' ] [ 1、4、7 ]


それで、Pythonを使って多くの便利で面白いことができるということのもう1つの証拠を得ました。 そして、それがどのように内部に配置されているかを理解すれば、美しくエレガントに行うこともできます。
もちろん、根本的に新しいものは何も作成しませんでしたが、ハーフタイプのエンティティを操作する必要があるプロジェクトでは、辞書とオブジェクトを選択する必要がなくなり、コードが少しきれいになりました。

これがなぜ悪いのか、問題をよりエレガントに解決する方法についてのコメントは歓迎します。

Source: https://habr.com/ru/post/J129201/


All Articles