1

次のクラスを検討してください。

class MyObject(object):

    __slots__ = ('_att1', '_att2')

    def __init__(self):
        self._att1 = None
        self._att2 = None

    @property
    def att1(self):
        """READ-ONLY property. """
        return self._att1

    @property
    def att2(self):
        """att2 property description. """
        return self._att2

    @att2.setter
    def att2(self, val):
        self._att2 = val

プロパティ デコレータを使用する利点は、ドキュメントを追加できることです。

a = MyObject()
help(a)
Help on MyObject in module __main__ object:

class MyObject(__builtin__.object)
 |  Methods defined here:
 |  
 |  __init__(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  att1
 |      READ-ONLY property.
 |  
 |  att2
 |      att2 property description.

クラスが最終ユーザーによって使用されることを意図している場合は、プロパティを使用して属性にアクセスしても問題ありません。

a.att2 = "new value"

ただし、からクラスを派生させる場合MyObject、派生クラスで「保護された」変数を使用することは受け入れられますか? あれは、

 class Derived(MyObject):

     __slots__ = ()

     def __init__(self):
         self._att1 = 1
         self._att2 = 0

     @property
     def att2(self):
         """att2 adds 1 to itself in every call. """
         self._att2 += 1
         return self._att2

     @att2.setter
     def att2(self, val):
         self._att2 = val

サードパーティのオブジェクトである場合MyObject、アンダースコア付きの属性は変更される可能性があるため、コードが変更されるとコードが壊れることを認識しています。ただし、MyObject基本クラスとして使用しているので、これを独自の派生クラスで使用しても問題ないと思います。

最近使い始めpylintたのですが、派生クラスで「保護された」変数を使用しているという事実に気付きました。ここに質問を投稿することにした理由は、これが受け入れられるものであるかどうかを知り、pylint. そうでない場合、これに対処する基準は何ですか?

もう 1 つ指摘したいのは、属性アクセスについてです。何が速いだろう

a.att1

また

a._att1

a.att1私が取り組んでいる例のように、python を実行すると、最初にオブジェクト ディクショナリまたはスロットが検索されるという印象を受けています。関数を検索するときにそれがそこにない場合( の場合のように__getattr__)。クラス定義で多くの計算を行う場合、デコレータで定義したものではなく、ディクショナリまたはスロットにあるものにアクセスします。これは python コミュニティの間で悪い習慣と見なされますか? pylintのデフォルト設定ではそうではないことがわかり、良い基準を念頭に置いて作業を続けたいので、私はこれを尋ねているだけです。

編集:

__slots__時期尚早の最適化の議論には入らないようにしましょう。可能であれば、元の投稿では使用せず__slots__、すべてがオブジェクトの辞書にあると仮定してください。

4

3 に答える 3

5

アンダースコア付きの属性は「保護」ではなく「非公開」であり、変更される可能性があります。あなたのクラスがそれから派生したものであっても。このデータにアクセスするには、parent プロパティを使用する必要があります。

パフォーマンスについて話す。もちろん、プロパティへのアクセスは関数呼び出しを伴うため、属性へのアクセスよりも少し遅くなりますが、気にする必要はありません。ちなみに、これとは何の関係もありませ__getattr__ん。プロパティも通常の属性として辞書で検索され、記述子プロトコルを実装するだけです。

于 2013-06-01T19:42:22.510 に答える
4

簡単な答え: 「時期尚早の最適化は諸悪の根源です。」

pylintを信頼してください。本当にパフォーマンスの問題があるかどうかを確認してください。はいの場合は、プロファイリングしてから、ボトルネックを探します。ループまたはデータ構造を変更すると、おそらくはるかに効果的です。

于 2013-06-01T19:37:38.540 に答える