オーバーライドされた属性アクセスが (期待どおりに) 機能しない
-
18-09-2019 - |
質問
次のモジュールの主な目的は、一部の名前に一種の「定数」セマンティクスを提供することです。
class ConstantError(Exception):
def __init__(self, msg):
self._msg = msg
class Constant(object):
def __init__(self, name):
self._name = name
def __get__(self, instance, owner):
return instance._content[self._name]
def __set__(self, instance, value):
raise ConstantError, 'Illegal use of constant'
class Constants(object):
def __init__(self, content):
self._content = content
for k in self._content:
setattr(self, k, Constant(k))
num_const = Constants({
'one': 1,
'two': 2
})
使用する場合:
>>> from const import *
>>> dir(num_const)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_content', 'one', 'two']
それで one
そして two
は存在しますが、属性へのアクセスは残念です:
>>> num_const.one
<const.Constant object at 0x7faef4871710>
>>>
私が期待しているところ 1
この場合。私のどこが間違っているのでしょうか?
解決
記述子プロトコルは以下でのみ機能します。 クラスの属性, 、クラスのインスタンスの属性ではありません。を参照してください。 記述子のハウツーガイド
他のヒント
あなたには次のものが欠けています str() または ユニコード定数の () メソッド。
追加:
def __unicode__(self):
return self._name
私は、彼らが操作できるようにPythonが記述機械へのアクセスからクラスを防ぐことだと思います。それ以外の場合は、ディスクリプタを操作する「魔法」の機能のいくつかの種類せずに非常にトリッキー得ることができる、とあなたはPythonの試行を気づいた場合はアクセス可能言語機械の多くを維持します。これを回避するために、私は多くの場合、その場でクラスを生成しました。たとえば、定数クラスがそうのように宣言することができます:
class Constants(object):
def __new__(cls, content):
class _Constants(object):
pass
constants = _Constants
constants._content = content
for k in constants._content:
setattr(_Constants, k, Constant(k))
return constants
が、本当に、あなたの目的のために、あなたはとのより良いかもしれません。
class Constants(object):
def __init__(self, content):
self._content = content
def __getattr__(self,key):
return self._content[key]
所属していません StackOverflow