私は同様の混乱で、この質問に出くわした、と私は自分自身のためにそれに答えた後、繁栄のためにここに私の調査結果を報告することが賢明と思われました。
ThiefMasterがすでに指摘しているように、「owner」パラメータはclassproperty
のような構成を可能にします。場合によっては、クラスにメソッド以外の属性としてマスクされたメソッドを持たせ、owner
パラメータを使用すると、通常の記述子でそれを行うことができます。
しかし、これは半分の質問です。 「読み取り専用」問題については、ここに私が見つけたものがあります:
私は最初に答えを見つけました:http://martyalchin.com/2007/nov/23/python-descriptors-part-1-of-2/。私は最初にそれを理解していなかったし、私の頭を包むのに5分ほどかかった。ついに私に納得させたのは、例を思い付くことでした。
最も一般的な記述子を考えてみましょう:property
。変数countにアクセスした回数であるプロパティcountを使って、簡単なサンプルクラスを使いましょう。
class MyClass(object):
def __init__(self):
self._count = 0
@property
def count(self):
tmp = self._count
self._count += 1
return tmp
@count.setter
def setcount(self):
raise AttributeError('read-only attribute')
@count.deleter
def delcount(self):
raise AttributeError('read-only attribute')
我々はすでに確立されてきたように、__get__
機能のowner
パラメータを使用すると、クラスレベルで属性にアクセスすると、__get__
機能はGETATTR呼び出しをインターセプトすることを意味します。そのような場合、property
のコードはクラスレベルでアクセスされると単純にreturns the property itselfになりますが、何らかの静的な値を返すような何かを行うことができます。
ここで、__set__
と__del__
が同じように動作した場合を考えてみましょう。 __set__
と__del__
メソッドは、インスタンスレベルに加えて、クラスレベルですべてsetattr
とdelattr
の呼び出しをインターセプトします。
これは、MyClass
の「カウント」属性が実質的にの変更不可能なであることを意味します。 Javaのようなコンパイルされた静的な言語でプログラミングすることに慣れていた場合、アプリケーションコード内でクラスを変更することはできないので、これはあまり面白く見えません。しかしPythonでは、そうすることができます。クラスはオブジェクトとみなされ、それらの属性のいずれかを動的に割り当てることができます。たとえば、MyClass
がサードパーティのモジュールの一部であり、MyClass
がアプリケーションにほぼ完全に対応しているとします(ただし、count
のコード以外に他のコードがあるとします)。代わりに、すべての単一のインスタンスに対して常に10を返すようにします。私たちは、次の操作を行うことができます:setattr(MyClass, 'count')
への呼び出しをインターセプト
>>> MyClass.count = 10
>>> myinstance = MyClass()
>>> myinstance.count
10
__set__
場合は、実際にMyClassのを変更する方法はありません。代わりに、setcount
のコードはそれを傍受し、何もできませんでした。唯一の解決策は、MyClassのソースコードを編集することです。 (サブクラスでそれを定義すると、setattr
コードがまだ呼び出されると思うので、サブクラスで上書きできるかどうかは確かではありませんが、私はまだ分かりません。 )
「これはまさに私が欲しいものです!私はを意図的には私のクラスの属性を再割り当てしたくありませんでした!そのために、私が言うことができるのは、素朴な記述子を使ってあなたが望むものは不可能であるということです。私は上記の推論にあなたを導きます。クラス属性を再割り当てできるようにすることは、現在のPythonのやり方に沿ったものです。あなたが本当に、が本当には読み取り専用のクラス属性を作成したい場合は
、私はどのようにあなたを伝えることができるとは思いません。解決策がある場合でも、それはおそらく、メタクラスを使っ伴うだろうとメタクラスのproperty
を作成したりSETATTRと delattr のメタクラスのコードを変更するのいずれか。しかし、これはディープマジックであり、この答えの範囲をはるかに超えています(そして自分自身のPythonの能力)。
はい、私は「所有者」が何であるかを知っていますが、この「所有者」はどのように使用できますか?私は '所有者 'の存在の点を見ていない。そして私はあなたが私の2番目の質問に答えたとは思わない。 – Alcott
それは一つです、upvoted。では、**読み取り専用**の問題はどうですか? – Alcott
私の推測では、記述子はクラスレベルで記述されるのではなく、インスタンスレベルでのみ記述されることになります。 – ThiefMaster