-1

self.variable構文を使用して変数を作成することと、それなしで変数を作成することの違いは何ですか?

私はそれをテストしていましたが、インスタンスから両方にアクセスできます。

class TestClass(object):
    j = 10
    def __init__(self):
        self.i = 20

if __name__ == '__main__':
    testInstance = TestClass()
    print testInstance.i
    print testInstance.j

ただし、の場所を入れ替えるとselfエラーになります。

class TestClass(object):
    self.j = 10
    def __init__(self):
        i = 20

if __name__ == '__main__':
    testInstance = TestClass()
    print testInstance.i
    print testInstance.j  

>>NameError: name 'self' is not defined

だから私は、自己が初期化において特別な役割を果たしていることを収集します。しかし、私はそれが何であるかを完全には理解していません。

4

2 に答える 2

6

selfクラスの現在のインスタンスを参照します。関数本体の外部で変数を宣言する場合は、インスタンスではなくクラス自体を参照しているため、クラスのすべてのインスタンスはその属性に対して同じ値を共有します。

さらに、(インスタンスの一部ではなく)クラスの一部として宣言された変数は、クラス自体の一部としてアクセスできます。

class Foo(object):
    a = 1

one = Foo()
two = Foo()

Foo.a = 3

この値はクラス全体であるため、クラスから直接読み取ることができるだけではありません。

print Foo.a # prints 3

ただし、クラスのすべてのインスタンスの値も変更されます。

print one.a # prints 3
print two.a # prints 3

ただし、これは、クラス変数をインスタンス変数でオーバーライドしない場合にのみ当てはまることに注意してください。たとえば、次を作成した場合:

class Bar(object)
    a = 1
    def __init__(self):
        self.a = 2

そして、次のことを行いました。

one = Bar()
two = Bar()
two.a = 3

次に、次の結果が得られます。

print Bar.a # prints "1"
print one.a # prints "2"
print two.a # prints "3"

コメントに記載されているように、に割り当てると、two.aそのインスタンスにインスタンスローカルエントリが作成されます。これにより、afromがオーバーライドされますBar。したがって、なぜBar.a1であるのにtwo.a3であるのかがわかります。

于 2012-10-10T02:30:32.773 に答える
0

jAmberが指すクラス変数です。さて、あなたがC ++のバックグラウンドから来たのなら、それはポインタselfに似ています。thisPythonはポインターを処理しませんselfが、クラスの現在のインスタンスを参照するのと同様の役割を果たします。

Pythonの方法では、explicit is better than implicit。C ++では、の可用性 thisは通常、クラスごとに想定されています。一方、Pythonは、self最初の引数として各インスタンスメソッドに明示的に渡します。

したがってself、インスタンスメソッドのスコープ内でのみ使用可能であり、それundefinedを使用しようとした場所で使用できます。

インスタンスメソッドに明示的に渡すselfようになっているので、必要に応じて別の名前で呼び出すこともできます-

>>> class Foo:
...     b = 20
...     def __init__(them):
...             them.beep = "weee"
... 
>>> f = Foo()
>>> f.beep
'weee'
于 2012-10-10T02:56:06.197 に答える