get / setパターン(Python)を使用していますか?


82

get / setの使用は(さまざまな理由で)Javaで一般的な方法のようですが、これを使用するPythonコードはほとんど見当たりません。

Pythonでget / setメソッドを使用または回避するのはなぜですか?


みんなからの素晴らしい反応。確かに、この質問はこの1つのstackoverflow.com/questions/1022970/の派生物です…しかし、私は「J」という言葉の観点からそれを見ている大勢の人々に襲われたようです。再び正気で私の信仰を復元するための...感謝
エイブリー・ペイン

1
コンテキストは重要であり、ここではPythonとJavaは単純に異なります。(ただし、SOでタグを使用しているため、タイトルからPythonを削除しました。;)

回答:


59

クールなリンク:PythonはJavaではありません:)

Javaでは、ゲッターとセッターを使用する必要があります。パブリックフィールドを使用すると、後でゲッターとセッターを使用することに戻って気が変わる機会がないためです。したがって、Javaでは、雑用を前もって邪魔にならないようにすることもできます。Pythonでは、これはばかげています。クラスのクライアントに影響を与えることなく、通常の属性から始めて、いつでも気が変わってしまうからです。したがって、ゲッターやセッターを作成しないでください。


3
さらに、セッター/ゲッターは、特にPythonでパフォーマンスコストを追加します。
Nick Dandoulakis 2010

4
これクラス設計者に追加の負担をかけます。その場合、インスタンス変数は暗黙的にクラスのパブリックAPIの一部になります。クラスをレイアウトするときは、外部からアクセスするインスタンス変数と、実際にはクラス実装の一部にすぎないインスタンス変数を明確に検討してください。内部実装のものの前に「_」を付けます。これは、実装が変更された場合、この変数も変更されるか、完全になくなる可能性があることを示すPythonの警告サインです。そうしないと、実装の知識がクラスから漏れてしまい、後で変更するのが難しくなります。
PaulMcG 2010

8
@Nick D:アクセサーはPythonで速度の最適化を行うのに適切な場所ではないと思います。
wRAR 2010

1
@Nick D:つまり、これはパフォーマンスではなく読みやすさを促進するインタープリター型言語なので、プログラムを最適化するためのより良い場所がたくさんあります。
wRAR 2010

2
@Paul:1つまたは2つの先頭の下線で名前が付けられていない限り、内部属性ではありません(前者の形式は、Pythonの通常とは異なる名前マングリングを行うため、一般的に好まれます)。ドキュメントを作成したくなく、この問題が気になる場合は、すべてのインスタンス属性にデフォルトで_nameを使用するだけです。

113

Pythonでは、公開されているため、属性に直接アクセスできます。

class MyClass:

    def __init__(self):
        self.my_attribute = 0  

my_object = MyClass()
my_object.my_attribute = 1 # etc.

属性へのアクセスまたは変更で何かを実行したい場合は、プロパティを使用できます

class MyClass:

    def __init__(self):
        self._my_attribute = 0

    @property
    def my_attribute(self):
        # Do something if you want
        return self._my_attribute

    @my_attribute.setter
    def my_attribute(self, value):
        # Do something if you want
        self._my_attribute = value

重要なのは、クライアントコードが同じままであるということです。


30

これがGuidovanRossumがMastermindsofProgrammingでそれについて言っていることです

「言葉と戦う」とはどういう意味ですか?

Guido:それは通常、彼らが別の言語でうまく機能する習慣を継続しようとしていることを意味します。

[...]人々はすべてをクラスに変え、すべてのアクセスをアクセサーメソッドに変え
ます。これはPythonで行うのは賢明なことではありません。より冗長なコードがあり
、デバッグが難しく、実行速度が大幅に低下します。「FORTRANはどの言語でも書けますか?」という表現をご存知ですか?Javaはどの言語でも書くことができます。


14

いいえ、それは非Pythonです。一般的に受け入れられている方法は、通常のデータ属性を使用し、より複雑なget / setロジックを必要とするものをプロパティに置き換えることです。


13
+1:「私たちはみんなここで大人です」。コードが表示されます。「private」と「getter / setter」は、すべてのコードが表示されている場合、値を作成しません。
S.Lott 2010

7

あなたの質問に対する簡単な答えはノーです。必要に応じてプロパティを使用する必要があります。Ryan Tamyokoは、彼の記事Getters / Setters / Fuxorsで長い答えを提供しています

これらすべてから取り除く基本的な価値は、コードのすべての行がプログラマーにとって何らかの価値または意味を持っていることを確認するよう努めたいということです。プログラミング言語は人間向けであり、機械向けではありません。何も役に立たない、読みにくい、または退屈に見えるコードがある場合は、Pythonにそれを削除できる言語機能がある可能性があります。


5

あなたの観察は正しいです。これはPythonプログラミングの通常のスタイルではありません。属性はすべてパブリックであるため、(クラスやインスタンスだけでなく)属性を持つオブジェクトの属性を使用する場合と同じように、属性にアクセス(取得、設定、削除)するだけです。彼らのPythonコードはPython構文を使用したJavaのように見えるので、JavaプログラマーがいつPythonを学ぶかは簡単にわかります。

私は間違いなく、特にフィリップの有名な記事へのマキシのリンク@、すべての以前のポスターに同意し、クラスとインスタンスの属性の設定(および取得)の標準的な方法よりも複雑なものは(もっと一般化するのか記述)のプロパティを使用することを最大の提案@属性の取得と設定をカスタマイズします!(これには、プライベート、保護、フレンド、またはパブリック以外のものが必要な場合に必要なポリシーの独自のカスタマイズバージョンを追加できることが含まれます。)

興味深いデモとして、コアPythonプログラミング(第13章、セクション13.16)で、記述子を使用して属性をメモリではなくディスクに格納する例を思いつきました。はい、それは永続ストレージの奇妙な形だが、それはないあなたに何ができるかの例を示して!

同様に役立つと思われる別の関連記事は次のとおり です。Python:複数のプロパティ、1つのセッター/ゲッター


0

私はその答えのためにここに来ました(残念ながら私はできませんでした)。しかし、私他の場所で回避策を見つけました。以下のコードは、getの代わりになる可能性があります
class get_var_lis: def __init__(self): pass def __call__(self): return [2,3,4] def __iter__(self): return iter([2,3,4]) some_other_var = get_var_lis
これは単なる回避策です。上記の概念を使用することにより、uはpyでもget / set方法論を簡単に構築できます。


-10

先生は、アクセサー関数をいつ使用すべきかを説明するクラスの1つの例を示しました。

class Woman(Human):
    def getAge(self):
        if self.age > 30:
            return super().getAge() - 10
        else:
            return super().getAge()

反対票は出しませんでしたが、チャイムを鳴らそうと思いました。議論のポイントは、「Pythonでプロパティに直接アクセスするためにget()/ set()が必要な理由」です。Javaには、これを望ましいものにする言語...機能...があります。Pythonでは、それほど多くはありません。
エイブリーペイン

7
質問に実際に答えていないことは別として、この答えで使用されている例は不快です。あなたの先生がそれを使用したという主張は、その性差別を正当化するものではありません。
Touzen 2015

これが性差別を示しているのではないかと思います。単にあなたの素朴さです。私の祖母の世代では、多くの女性が自分の年齢が実際よりも数年若いと冗談を言っていました。それに、とにかく答えとは何の関係もありません。
JohanSnowgoose19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.