2017-03-08 4 views
1
xTestPropertyのインスタンスである場合は、このサンプルコードで

、私は決定したいと思います:ディスクリプタのクラスを決定する方法は?

class TestProperty(object): 
    def __init__(self, name): 
     self._name = name 

    def __get__(self, instance, cls): 
     return getattr(instance, self._name) 

    def __set_(self, instance, value): 
     setattr(instance, self._name, value) 

class Test(object): 
    x = TestProperty("x") 

print isinstance(Test.x, TestProperty) 

をしかし、私は次の例外を取得:

Traceback (most recent call last): 
    File "/home/zenoss/testproperties.py", line 14, in <module> 
    print isinstance(Test.x, TestProperty) 
    File "/home/zenoss/testproperties.py", line 6, in __get__ 
    return getattr(instance, self._name) 
AttributeError: 'NoneType' object has no attribute 'x' 

があれば、属性を伝えるためにとにかくがあります記述子の場合はクラスのインスタンスですか?現在__get__

答えて

2

は、Test.xAttributeErrorの原因となるクラスを使用して記述子にアクセスするコードは、instanceNoneを渡されたときからです。あなたはx = TestProperty("x")で、知っているかもしれないとして、インスタンスを通じてx属性にアクセスすると、別の原因となります、ところで

>>> class TestProperty(object): 
...  def __init__(self, name): 
...   self._name = name 
...  def __get__(self, instance, cls): 
...   if instance is None: # To handle access through class, not instance 
...    return self  # returns the TestProperty instance itself. 
...   return getattr(instance, self._name) 
...  def __set_(self, instance, value): 
...   setattr(instance, self._name, value) 
... 
>>> class Test(object): 
...  x = TestProperty("x") 
... 
>>> isinstance(Test.x, TestProperty) 
True 

:(=>getattr(None, 'x') =>None.x

あなたは、このようなケースを処理するために__get__を変更する必要があります例外は、スタックオーバーフローが発生するまで、__get__( - > getattr(..) - > __get__ - > getattr(..) - > ...)を再帰的に呼び出します。

+0

ありがとう、 'インスタンスがNone'のときに' self'を返すことはそのトリックを行います。 – Ben

+0

@Ben、よろしくお願いします。ハッピーパイソンハッキング! – falsetru

0

プロパティを実装するための最良の方法は、@propertyデコレータである:私はそれを実行したときにそれはTrueを返し

class TestProperty(object): 

    def __init__(self, name): 
     self._name = name 

    @property 
    def name(self): 
     """Getter for '_name'.""" 
     return self._name 

    @name.setter 
    def name(self, value): 
     """Setter for '_name'.""" 
     self._name = value 

class Test(object): 
    x = TestProperty("x") 

print(isinstance(Test.x, TestProperty)) 

@propertyのドキュメントをhttps://docs.python.org/3/library/functions.html#propertyに表示してください。

関連する問題