2016-05-19 9 views
4

予約語propertyを使用している神を捨て去った神があります。間違っています。継承される基本クラスでは、基本的に実装されています。プロパティ予約語の誤用

class TestClass(object): 

    def __init__(self, property): 
     self._property = property 

    @property 
    def property(self): 
     return self._property 


test = TestClass('test property') 
print(test.property) 

エラーなく実行されます。

---> 10  @property 
    11  def other_property(self): 
    12   print('test other property') 

TypeError: 'property' object is not callable 

をあなたはローカル名前空間内propertyを上書きしている知っているので:あなたはその下に別のメソッドを追加する場合は、スロー

class TestClass2(object): 

    def __init__(self, property): 
     self._property = property 

    @property 
    def property(self): 
     return self._property 

    @property 
    def other_property(self): 
     return 'test other property' 


test = TestClass2('test property') 
print(test.property) 
print(test.other_property) 

を取得します。

class TestClass3(object): 

    def __init__(self, property): 
     self._property = property 

    @property 
    def other_property(self): 
     return 'test other property' 

    @property 
    def property(self): 
     return self._property 


test = TestClass3('test property') 
print(test.property) 
print(test.other_property) 

あなたは常にあなたのクラスの一番下にあなたのproperty上書きを定義する場合は、これを回避することができます。 propertyメソッドが基底クラスでのみ定義されている場合は、名前空間を使用するため、継承したものからも機能します。

class TestClass4(TestClass): 

    def __init__(self, property): 
     super(TestClass4, self).__init__(property) 

    @property 
    def other_property(self): 
     return 'test other property' 


test = TestClass4('test property') 
print(test.property) 
print(test.other_property) 

私の義憤はほとんど変更されていないベースでproperty定義の定義の上に新しいメソッドを追加することを忘れないように持つ以外の理由GAAAAHが、我々は、レガシーコードの膨大な量で、この変数名を更新しなければならないと述べていますこれは実際に何かを壊すことはありませんか?

答えて

4

影の組み込みコマンドをいけない...あなたは、組み込みあなた_propertyメンバーを返すために代わり@propertyの完全

使用__getattr__をシャドーイングを回避することができ、すべてのほとんどのリファクタリングと ...

class TestClass(object): 
    def __init__(self): 
     self._property = 12 

    def __getattr__(self,item): 
     if item == "property": 
      #do your original getter code for `property` here ... 
      # now you have not overwritten the property keyword at all 
      return getattr(self,"_property") # just return the variable 
class TestClass2(TestClass): 
    def __init__(self): 
     self._property = 67 

print TestClass2().property 

class MySubClass(TestClass): 
    @property 
    def a_property(self): 
     return 5 

print MySubClass().property 
print MySubClass().a_property 

本当に、脇に、どんな良い理由もありません。@propertyをpythonで使用してください。後で他のプログラマーを混乱させ、実際に関数を呼び出すという事実を隠すことになります。私は定期的にそれをやっていました...私は非常に魅力的な理由がなければ避けるようになりました

+0

downvoter reason?私はdownvoteと私は好きですが、私は好奇心がなぜですか? –

+0

プロパティを使用する理由はたくさんあります。アクセサーやミューテータの代わりに属性を使ってapiを公開するのは非常に難しいですが、それはあなたが値を遅く計算できなかったり、人々が値を設定したときに副作用があったりすることを意味します。 'property'はあなたが両方の世界のベストを持つことを可能にします。 –

+1

Pythonにプライベート変数がありません...と私は言ったすべての意見だった私は確かにプロパティを使用して彼を止めていない...私の意見は、私の答えには無関係ですimhoは質問に正しい答えです。 –

0

propertyはいつでも別の名前に再マップすることができます。あなたが他のクラスの属性と一致しない名前を選ぶ限り、それはクラスの外部インターフェイスには公開されないので、名前を付けてもそれほど重要ではありません。

tproperty = property 

class Test(...) 

    @tproperty 
    def property(self): 
     .... 
+2

誰かが変数 'list'を命名した場合は、オリジナルの' list'を 'tlist'に割り当て、' list(x) 'の代わりに' tlist(x) 'を使うことをお勧めしますか? –

+0

いいえ、単に 'list()'の代わりに '[]'を使ってください:)しかし、真剣に、命名の決定が非常に悪かったとしても、APIを壊すことを常に*支持することはできません。 OPがAPIを破ってうまくいけば、彼は質問しなかっただろう、彼はちょうど名前を変更しただろう。組み込み関数を再マップすることは聞いたことではありません。「この関数はクラス定義の最後でなければなりません」という巨大なコメントよりも確かに望ましいです。 –

3

はい、あなた常には何も壊れませんpropertyメソッドの定義の上に新しいメソッドを追加する場合。だから、コード内のその効果に素敵な大きなコメントを入れてください。うまくいけば、派生クラスでpropertyをオーバーライドしたい人は、まず基底クラスを見て、あなたのコメントが表示されます...

ところで、__init__方法にproperty argはまたpropertyをシャドウが、私はそれは問題ではないことを推測します。

理想的には、誰かがこの混乱をきれいにする必要がありますが、それを行うのは費用対効果に優れていない可能性があると私は理解しています。

また、元のコーダーがなぜ最初に@propertyになったのか、私はやや戸惑っています。その構造体は、単純に静的属性を返すのではなく、属性の値を動的に計算する必要がある場合にのみ使用してください。おそらく彼らはPythonには新しく、Pythonでゲッターを行う方法だと言われました...

+0

mehローカルシャドウイングは、リファクタリングを計画しているのでなければ大したことではありませんが、リファクタリングのための+1は組み込みのシャドウではありません:P –

+0

コメントは意味をなさない...私は疲れていました。そのローカルスコープ内に新しいクラスを作成する予定です」 –

+0

実際の質問にお返事いただきありがとうございます。私は他の応答を受け入れています。なぜなら、影を取り除くための素晴らしい提案があるからです。 – TristanMatthews