私が書いたコードでは、より多くのpython記述子プロトコルを使い始めました。通常、デフォルトのPythonルックアップの魔法は私がやりたいことですが、ときどき私は__get__
メソッドの結果ではなく、ディスクリプタオブジェクト自体を取得したいと思っています。記述子のタイプを知りたい、または記述子に格納されている状態にアクセスしたい、あるいは何かをしたい。記述子マジックのないpython属性の参照?
私は正しい順序であると信じている名前空間を歩き回り、記述子であるかどうかにかかわらず、属性rawを返します。私は驚いていますが、これを行うために標準ライブラリに組み込まれた関数や何かを見つけることができません - 私はそれが存在しなければならないと私は気づいていないか、または適切な検索用語のためのグーグル
すでにこれを行っているPythonディストリビューションのどこかに(または類似の)機能がありますか?
ありがとうございます!
from inspect import isdatadescriptor
def namespaces(obj):
obj_dict = None
if hasattr(obj, '__dict__'):
obj_dict = object.__getattribute__(obj, '__dict__')
obj_class = type(obj)
return obj_dict, [t.__dict__ for t in obj_class.__mro__]
def getattr_raw(obj, name):
# get an attribute in the same resolution order one would normally,
# but do not call __get__ on the attribute even if it has one
obj_dict, class_dicts = namespaces(obj)
# look for a data descriptor in class hierarchy; it takes priority over
# the obj's dict if it exists
for d in class_dicts:
if name in d and isdatadescriptor(d[name]):
return d[name]
# look for the attribute in the object's dictionary
if obj_dict and name in obj_dict:
return obj_dict[name]
# look for the attribute anywhere in the class hierarchy
for d in class_dicts:
if name in d:
return d[name]
raise AttributeError
編集水曜日、10月28日、2009年
デニスの答えは私の記述がオブジェクト自体を得るために、私の記述子のクラスで使用するための規則を与えました。しかし、私は、ディスクリプタクラスのクラス階層全体を持っていた、と私はこれを避けるために、定型
def __get__(self, instance, instance_type):
if instance is None:
return self
...
とすべての__get__
機能を開始したくなかった、私はから記述子クラスツリーの継承のルートを作りました
def decorate_get(original_get):
def decorated_get(self, instance, instance_type):
if instance is None:
return self
return original_get(self, instance, instance_type)
return decorated_get
class InstanceOnlyDescriptor(object):
"""All __get__ functions are automatically wrapped with a decorator which
causes them to only be applied to instances. If __get__ is called on a
class, the decorator returns the descriptor itself, and the decorated
__get__ is not called.
"""
class __metaclass__(type):
def __new__(cls, name, bases, attrs):
if '__get__' in attrs:
attrs['__get__'] = decorate_get(attrs['__get__'])
return type.__new__(cls, name, bases, attrs)
時には、ディスクリプタオブジェクトが必要ですか?これはディスクリプタの中核的な期待に反するものです。ディスクリプタは属性のように見えます。なぜその基本的な期待を破るのですか?なぜこれを行うのですか?なぜ複雑なものを作るのですか? –
私がやっていることは、私にとっては複雑な感じではありませんが、私はそのデザインを実験していると言えるでしょう。 私の現在の特定のケースでは、私はゲーム内の武器の強さを返す記述子を持っています。その値は、記述子の状態(武器の強さ)とインスタンス(船の健康状態)の関数です。さまざまな種類の武器があります。通常は値の結果がほしいですが、いくつかのケースでは、どのような種類の兵器であるかを知る必要があります。記述子のタイプです。 そして、記述子がその記述子プロトコルの一部ではないメソッドを持っていて、それらを呼び出す場合はどうなりますか? –