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 

这几乎是我想要的类定义

稍后在 main 方法中,我创建一个实例并调用它a

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

这就是我发现a声明的变量main可用于该方法average 并使该方法工作的方法,我必须 self.a + self.b + self.c键入

这是什么原理?

我找到了相关的问题,但我真的不知道它们是否大致相同

4

3 回答 3

9

Barenames(如a, b, c)总是被限定为本地或全局的(除了嵌套函数,它们在您的代码中无处不在)。基本原理是,添加更多范围会不必要地使事情变得更加复杂——例如,如果在您self.a = a的裸名中a可以将范围限定为您想要的(相当于self.a),那么分配本身将毫无意义(给自己分配一个名称) ,所以你需要更复杂的规则。

self.a当您想要不同于barenames 的简单、直接和优化的行为时,仅使用限定名称(如裸名的范围总是由词法确定,依赖于环境的动态变化特征)。因此,除了可能怀念其他具有更复杂范围规则的语言之外,实际上没有理由使裸名的语义复杂化。

于 2010-04-20T18:18:59.583 回答
2

有几个原因,但最主要的原因来自 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 的存在(我们可以随心所欲地调用它,它不必是 self)允许区分self内部类和外部类。同样,这不是我经常做的事情,但是当我这样做时,它非常有用。

于 2010-04-20T18:19:49.853 回答
-1

所有实例变量都应该使用 self 调用

于 2010-04-20T18:16:55.220 回答