147

私はいくつかのpygame チュートリアルに従って Python を学んでいます。

その中で、キーワードselfが広範囲に使用されていることを発見しました。また、主に Java のバックグラウンドを持っているため、 selfと入力するのを忘れ続けていることがわかりました。たとえば、代わりにself.rect.centerxと入力rect.centerxします。なぜなら、私にとって、rectは既にクラスのメンバー変数だからです。

この状況で私が考えることができる Java の類似点は、メンバー変数へのすべての参照の前に this を付けなければならないことです

すべてのメンバー変数にselfのプレフィックスを付けて立ち往生していますか、またはそれらを宣言する必要がないようにする方法はありますか?

私が提案しているのはpythonicではなくても、それが可能かどうか知りたいです。

私はこれらの関連するSOの質問を見てきましたが、私が求めていることに完全には答えていません:

4

10 に答える 10

107

Python では、self を指定する必要があります。 その結果、完全なクラス定義が表示されていなくても、何がメンバーで何がそうでないかについて混乱することはありません。これは、次のような便利なプロパティにつながります: 非メンバーを誤って隠してコードを壊すメンバーを追加することはできません。

1 つの極端な例: クラスが持つ可能性のある基底クラスを知らなくてもクラスを記述でき、メンバーにアクセスしているかどうかを常に把握できます。

class A(some_function()):
  def f(self):
    self.member = 42
    self.method()

それが完全なコードです!(some_function は、ベースとして使用される型を返します。)

クラスのメソッドが動的に構成される別の方法:

class B(object):
  pass

print B()
# <__main__.B object at 0xb7e4082c>

def B_init(self):
  self.answer = 42
def B_str(self):
  return "<The answer is %s.>" % self.answer
# notice these functions require no knowledge of the actual class
# how hard are they to read and realize that "members" are used?

B.__init__ = B_init
B.__str__ = B_str

print B()
# <The answer is 42.>

これらの例は両方とも極端であり、毎日目にすることはありません。また、このようなコードを頻繁に記述する必要があることを示唆しているわけでもありませんが、明示的に必要とされる self の側面を明確に示しています。

于 2009-12-31T05:57:29.593 に答える
33

実際selfにはキーワードではなく、Python のインスタンス メソッドの最初のパラメーターに慣習的に付けられている名前です。また、最初のパラメーターはスキップできません。これは、メソッドが呼び出されているクラスのインスタンスを知るための唯一のメカニズムであるためです。

于 2009-12-31T05:56:37.977 に答える
21

たとえば、任意の名前を使用できます。

class test(object):
    def function(this, variable):
        this.variable = variable

あるいは

class test(object):
    def function(s, variable):
        s.variable = variable

しかし、スコープの名前を使用することに固執しています。

説得力のある理由がない限り、自分自身とは異なるものを使用することはお勧めしません。経験豊富なpythonistaにとって異質なものになるからです。

于 2009-12-31T06:18:24.050 に答える
9

はい、常に指定する必要がありますself。Python の哲学によれば、明示的は暗黙的よりも優れているためです。

また、Python でのプログラミング方法は Java でのプログラミング方法とは大きく異なることがわかります。したがって、selfオブジェクト内のすべてを投影するわけではないため、 の使用は減少する傾向にあります。むしろ、より適切にテストできるモジュール レベルの関数をより多く使用します。

ところで。最初は嫌いだったけど、今は逆に嫌い。インデント駆動のフロー制御についても同じです。

于 2009-12-31T05:54:33.333 に答える
4

「自己」は、クラスの現在のオブジェクト インスタンスの従来のプレースホルダーです。オブジェクトのプロパティ、フィールド、またはクラス内のメソッドを、「それ自体」を参照しているかのように参照する場合に使用されます。しかし、短くするために、Python プログラミング領域の誰かが "self" を使い始めました。他の領域では "this" を使用していますが、置き換えられないキーワードとして作成されています。コードの可読性を高めるために、むしろ「その」を使用しました。これは Python の優れた点の 1 つです。"self" 以外のオブジェクトのインスタンスに対して、独自のプレースホルダーを自由に選択できます。自己の例:

class UserAccount():    
    def __init__(self, user_type, username, password):
        self.user_type = user_type
        self.username = username            
        self.password = encrypt(password)        

    def get_password(self):
        return decrypt(self.password)

    def set_password(self, password):
        self.password = encrypt(password)

ここで、「self」を「its」に置き換えます。

class UserAccount():    
    def __init__(its, user_type, username, password):
        its.user_type = user_type
        its.username = username            
        its.password = encrypt(password)        

    def get_password(its):
        return decrypt(its.password)

    def set_password(its, password):
        its.password = encrypt(password)

今より読みやすいのはどれですか?

于 2012-12-18T19:47:05.780 に答える
3

self は、オブジェクトのメンバーにアクセスするための python 構文の一部であるため、あなたはそれに行き詰まっていると思います。

于 2009-12-31T05:53:27.343 に答える
3

From: Self Hell - よりステートフルな関数。

...ハイブリッド アプローチが最適です。実際に計算を行うクラス メソッドはすべてクロージャに移動し、構文をクリーンアップする拡張機能はクラスに保持する必要があります。クロージャーをクラスに詰め込み、クラスを名前空間のように扱います。クロージャーは本質的に静的関数であるため、クラス内であっても selfs* は必要ありません...

于 2015-11-12T11:22:16.287 に答える