1

以下は、Zed Shaw の「Learn Python the Hard Way」チュートリアル 40 のコード スニペットです。

class Song(object):

    def __init__(self, lyrics):
        self.lyrics = lyrics

    def sing_me_a_song(self):
        for line in self.lyrics:
            print line

Python で「sing_me_a_song」関数を定義するときに「self.lyrics」を使用できるのはなぜですか? 「 init 」の下で定義されている変数は、同じクラスの他の場所でも使用できるためですか?

ありがとう。

4

6 に答える 6

5

インスタンス変数

これをインスタンス変数と呼びます。self.「プレフィックス」として定義された変数は、オブジェクトの任意のメソッドで使用できます。通常、このような変数は で作成される__init__ため、オブジェクトが初期化された瞬間からアクセスできますが、他のメソッドでインスタンス変数を定義することもできます。例えば:

>>> class foo:
...     def fun(self):
...             self.heh=3
... 
>>> f = foo()
>>> f.heh 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: foo instance has no attribute 'heh'
>>> f.fun()
>>> f.heh
3

の外部でインスタンス変数を初期化する際の危険性に注意してください__init__。それらにアクセスしようとする前に、それらが初期化されているメソッドが呼び出されていない場合、エラーが発生します。

クラス変数

これを、クラスの任意のメソッドからアクセスできる別のタイプの変数である「クラス変数」と混同しないでください。クラス変数は、そのクラスの特定のオブジェクトだけでなく、クラス全体に対して設定できます。違いを示すために、インスタンス変数とクラス変数の両方を持つクラスの例を次に示します。

class MyClass:
    classVar = "I'm a class var."
    def __init__(self):
        self.instanceVar = "I'm an instance var."
    def fun(self):
        methodVar = "I'm a method var; I cannot be accessed outside of this method."
        self.instanceVar2 = "I'm another instance var, set outside of __init__."

「メソッド」と「関数」に関する注意

あなたの質問ではsing_me_a_song、「関数」と呼んでいます。実際には、クラスのメソッドSongです。これは通常の古い関数とは異なります。これは、基本的にクラスとリンクされているため、そのクラスのオブジェクトにもリンクされているためです。

于 2012-10-16T23:06:39.547 に答える
1

init関数を定義すると、最初の引数が「self」であることがわかります。これは、作成されるオブジェクトへの参照です。「self.lyrics = Lyrics」を実行すると、実際には変数ではなく、オブジェクトの属性に値が割り当てられます。

そのため、他の場所にアクセスしようとすると、表示されますが、変数であるためではありません! 通常のスコープ ルールに従っていれば、表示されるべきではないと考えるのは正しいことです。ただし、これは変数ではなく、オブジェクトへの参照がある限り、どのコードでも self.lyrics の値にアクセスできます。

例えば:

test = Song(["This is some lyrics."])
test.sing_me_a_song() #this works
print test.lyrics[0] #but so does this!
于 2012-10-16T23:10:48.223 に答える
0

Java や C++ がクラスを定義するのとまったく同じように、クラス定義ではないことを認識することが重要です。

Self は動的オブジェクトです。それ自体であろうと、他のオブジェクトであろうと、 myObj.newField = value 常に有効なことです。オブジェクトの初期化時にinitが実行されたため、self.lyrics 要素があります。

あなたが持つことができた


def foo(self):
    self.thing = "turtle"

そして、foo の後に呼び出された任意の関数で、self.thing を参照できます。(これはおそらく非常に悪い考えですが、構文的に間違っているわけではありません)。

于 2012-10-16T23:10:43.120 に答える
0

名前selfは特別なものではありません。Python では、オブジェクトのすべてのメソッドは、そのオブジェクトへの参照を最初のパラメーターとして自動的に受け取ります。

これは、__init__(コンストラクター)メソッドでlyrics、オブジェクトの属性を設定することを意味します。後で を呼び出すとsing_me_a_song、歌詞属性を持つ同じオブジェクトへの参照が取得されます。

于 2012-10-16T23:10:53.010 に答える
0

コードに従って、self.lyricsクラスのコンストラクターで定義されます。オブジェクトを作成するときは、常にコンストラクターが最初に呼び出されます。これによりself.lyrics、他のクラス メソッドで使用できます。

于 2012-10-16T23:09:11.030 に答える
0

selfSongメソッドが呼び出されているクラスの実際のインスタンスを参照するために使用されます。たとえば、あなたがそうするなら...

foo = Song("hello")
bar = Song("world")

次にfoo.lyricsに設定され"hello"、 にbar.lyrics設定され"world"ます。次に、これらのインスタンスのいずれかでメソッドを呼び出すと、次のようになります...

foo.sing_me_a_song()

次に、メソッドが に設定されて呼び出され、 にself設定された のインスタンスであるため、foo検索self.lyricsされます。"hello"foolyrics"hello"

于 2012-10-16T23:10:01.167 に答える