2012-04-29 5 views
9
class Books(): 
    def __init__(self): 
     self.__dict__['referTable'] = 1 

    @property 
    def referTable(self): 
     return 2 

book = Books() 
print(book.referTable) 
print(book.__dict__['referTable']) 

実行:property()機能は、データ記述子として実装されているプロパティの非データバージョンを組み込んでいますか?

[email protected]:~/Desktop$ python3 test.py 
2 
1 

Books.referTablebeing a data descriptorbook.__dict__['referTable']の陰にされていません。 したがって、インスタンスはプロパティの動作をオーバーライドできません。

propertyの内蔵ディスクリプタではなく、私自身のディスクリプタを使用する必要があります。 propertyのような組み込みの記述子がありますが、それは非データですか?

+1

ここで何をしようとしていますか?関数で '' @ property''を使う方法を変えることで達成できないことを達成しようとしていますか? –

+0

@Lattyware、私は怠惰な記述子を作ろうとしています。時々私は '__init__'で' referTable'を設定したいと思っています。他の場合には、ディスクリプタに値を計算させ、 '__init__'で行ったのと同じ方法でディスクリプタをオーバーライドします。ここでは(http://blog.pythonisito.com/2008/08/lazy-descriptors.html)それは私にとってはうまくいく、それのための別の記述子になっています。私の場合は、可能であれば組み込み記述子を使用して単純化し、 'property'が私のためには機能しません。 – warvariuc

+0

「簡略化」ですか?あなたは単純化したいものを明確にすることができますか?なぜリンクしている例があなたのために働かないのですか? –

答えて

5

なぜこのような単純なもの、私のコメントに展開するには:

>>> class Books(): 
...  def __init__(self): 
...   self.__dict__['referTable'] = 1 
...  @property 
...  def referTable(self): 
...   try: 
...    return self.__dict__['referTable'] 
...   except KeyError: 
...    return 2 
... 
>>> a = Books() 
>>> a.referTable 
1 
>>> del a.__dict__['referTable'] 
>>> a.referTable 
2 

さて、私はこれは良いデザインだとは思わないことに注意したいのですが、あなたがはるかに良いと思います直接__dict__にアクセスするのではなく、プライベート変数を使用します。例えば:要するに

class Books(): 
    def __init__(self): 
     self._referTable = 1 

    @property 
    def referTable(self): 
     return self._referTable if self._referTable else 2 

、答えはノーである、あなたはPythonの標準ライブラリにしたいように動作しますproperty()への代替手段はありません。

2

内蔵の非データディスクリプタと非常に似たものがある - クラス属性:

class Books(): 

    referTable = 'default' 

    def __init__(self, referTable=None): 
     if referTable is not None: 
      self.referTable = referTable 


book = Books() 
print(book.referTable) 
# default 
book.referTable = 'something specific' 
print(book.referTable) 
# something specific 

あなたはより多くのプロパティのようなものが必要な場合(たとえば、あなたは関数がいくつかをしたいが、 )初めて重持ち上げるが、その後、すべての将来の参照のためにその最初の値を使用して、あなたはそれを自分で構築する必要があります:

以下の結果を得
class OneTime(object): 

    def __init__(self, method): 
     self.name = method.__name__ 
     self.method = method 

    def __get__(self, inst, cls): 
     if inst is None: 
      return self 
     result = self.method(inst) 
     inst.__dict__[self.name] = result 
     return result 

class Books(object): 

    @OneTime 
    def referTable(self): 
     print 'calculating' 
     return 1 * 2 * 3 * 4 * 5 

b = Books() 
print b.__dict__ 
print b.referTable 
print b.__dict__ 
print b.referTable 

{} 
calculating 
120 
{'referTable': 120} 
120 
関連する問題