7

私は自分のpythonを教えていて、いくつかのサンプルコードをこれに翻訳していました

class Student(object):
    def __init__( self, name, a,b,c ):
        self.name = name
        self.a = a
        self.b = b
        self.c = c

    def average(self):
        return ( a+b+c ) / 3.0 

これは、ほとんど私の意図したクラス定義です

メイン メソッドの後半で、インスタンスを作成して呼び出しますa

if __name__ == "__main__" :
    a = Student( "Oscar", 10, 10, 10 )

aそれが、で宣言された変数がmainメソッドで使用可能であることを確認する方法average であり、そのメソッドを機能させるには、 self.a + self.b + self.c代わりに入力する必要があります

これの根拠は何ですか?

関連する質問を見つけましたが、それらがほぼ同じかどうかはよくわかりません

4

3 に答える 3

9

ベアネーム ( ab、 などc) は、常にローカルまたはグローバルとしてスコープされます (コード内のどこにもないネストされた関数を保存します)。理論的根拠は、さらにスコープを追加すると、不必要に物事が複雑になるということです。たとえば、self.a = aベアネームで、a必要と思われるものを意味するようにスコープを設定できる場合(と同等self.a)、割り当て自体は無意味になります(それ自体に名前を割り当てる) 、さらに複雑なルールが必要になります。

self.aベアネームのシンプルで直接的で最適化された動作とは異なる何かが必要な場合は、修飾名 ( など) を使用するだけで、はるかに簡単なアプローチになります。完全に機能し、複雑なルールはまったくなく、コンパイラーが効果的に物事を最適化できます (例えばベアネームのスコープは、動的に変化する環境の特性に依存するのではなく、常に語彙的に決定されます)。したがって、より複雑なスコープ規則を持つ他の言語への懐かしさ以外に、ベアネームのセマンティクスを複雑にする理由は実際にはありません。

于 2010-04-20T18:18:59.583 に答える
2

いくつかの理由がありますが、主な理由は Zen of Python からのものです。「明示的は暗黙的よりも優れている」。C++ のような言語では、クラスのメソッドには常にthis、メソッドが呼び出されるたびにスタックにプッシュされる暗黙の引数があります。この場合、bグローバル変数と同様にインスタンス変数が存在するとb、ユーザーはb一方を参照するだけで、もう一方が使用されることに気付かないことがあります。そのため、Python では、混乱を避けるためにスコープを明示する必要があります。

そうは言っても、他の理由もあります。たとえば、クラスの外部で関数を定義し、実行時にクラスにアタッチすることがあります。例えば:

def log(self):
    print "some library function requires all objects to have a log method"
    print "unfortunately we're using the Student class, which doesn't have one"
    print "this class is defined in a separate library, so we can't add the method"
    print "fortunately, we can just add the method dynamically at runtime"

Student.log = log

ここで、self明示的であるという事実により、クラスの外で関数を定義し、それをそのクラスにアタッチすることは簡単になります。私はこの種のことを信じられないほど頻繁に行うわけではありませんが、そうするときは非常に役立ちます.

さらに複雑な例を次に示します。単体テストなどの目的で、別のクラス内にクラスを定義したいとします。

class SomeUnitTests(TestCase):
    def test_something(self):
        class SomeMockObject(SomeActualObject):
            def foo(self2):
                self.assertEqual(self2.x, SOME_CONSTANT)

        some_lib.do_something_with(SomeMockObject)

selfここでは、明示的な自己 (任意の名前を付けることができます。自己である必要はありません) の存在により、内部クラスと外部クラスを区別することができます。繰り返しますが、これは私が頻繁に行うことではありませんが、そうすると信じられないほど役に立ちます。

于 2010-04-20T18:19:49.853 に答える
-1

All instance variables should be called using self

于 2010-04-20T18:16:55.220 に答える