型の__dict__
は、読み取り専用のdictproxy
オブジェクトです。その目的が何なのか知りたい。 「組み込み型の変更を許可しない」ためだけですか?これを回避できる方法を見つけました。組み込み型を変更するのは良い考えではないことを私は知っています。しかし、私はCythonのcdef class
をオンザフライで変更しようとしています。
__dict__
のcdef class
をこのように変更するのに危険なものはありますか?
コードは次のとおりです。
import gc
gc.get_referents(float.__dict__)[0]["square"] = lambda self: self*self
(3.14).square()
dictproxy
(クラスにあります)の目的は、Pythonインタープリターでの最適化を可能にし、その安定性を確保することです。最適化の要件の詳細については、以下のMartijnPietersコメントを参照してください。 、明らかにclass.__dict__
のキーは常に文字列であることに依存しています。
dictproxy
は、インタプリタの特定の不安定性から保護する役割も果たしているようです。このような不安定性の詳細については、python.orgで「 __ dict__読み取り専用のバイパス 」というタイトルで説明されているバグレポートとバグ修正を参照してください。ある種のプロキシメカニズムを使用しない場合は、__dict__
に書き込むことができます。書き込み可能であれば削除可能です。バグレポートでは、__dict__
が削除され、インタプリタがクラッシュする可能性があるいくつかのシナリオについて説明しています。
これは、canが直接または__setitem__()
:
instance.__dict__['x'] = 1
また、インスタンス__dict__
は削除できます。削除された場合、属性の割り当てが試行されたときに自動的に再作成されます。
del instance.__dict__ instance.a = 1 instance.__dict__
つまり、dictproxy
を使用すると、クラスがより最適に動作し、インタープリターがより安定します。
__dict__
は、クラス属性を保持する名前空間オブジェクトです。
__dict__
自体を変更しない限り、dictオブジェクトの変更に問題はありません。
例:
//good
MyClass.x = 1
//bad
MyClass.__dict__['x'] = 1
//good
m = MyClass()
m.x = 1
//also good
m.__dict__['x'] = 1
Pythonドキュメント[ [〜#〜] link [〜#〜] ]:Attribute assignment updates the module’s namespace dictionary, e.g., m.x = 1 is equivalent to m.__dict__["x"] = 1.
したがって、dictのオブジェクトを変更しても問題はありません。
さらに:
クラスの属性を変更できるため、クラスのdictは常に書き込み可能です。
__dict__ | The namespace supporting arbitrary function attributes. | Writable
注
Cpythonの実装はpyhtonとは少し異なる可能性がありますが、ドキュメントから読み取れるように、言及されていません。