想想这个例子:

class MyClass:
    def func(self, name):
        self.name = name

我知道self引用MyClass的特定实例。但是为什么func必须显式地包含self作为参数呢?为什么我们需要在方法的代码中使用self ?其他一些语言将其隐式化,或者使用特殊的语法。


有关设计决策的语言无关性考虑,请参见强制显式使用this/self指针的好处是什么?

要关闭OP省略方法的self形参并获得TypeError的调试问题,请使用TypeError: method()接受1个位置参数,但给出了2个。如果OP省略了self。在方法体中得到一个NameError,考虑如何在类中调用函数?


当前回答

与前面提到的所有其他原因一样,它允许更容易地访问被覆盖的方法;你可以调用Class.some_method(inst)。

举个例子说明它的用处:

class C1(object):
    def __init__(self):
         print "C1 init"

class C2(C1):
    def __init__(self): #overrides C1.__init__
        print "C2 init"
        C1.__init__(self) #but we still want C1 to init the class too
>>> C2()
"C2 init"
"C1 init"

其他回答

因为按照python的设计,其他的选择几乎行不通。Python被设计为允许在隐式this (a-la Java/ c++)或显式@ (a-la ruby)都不能工作的上下文中定义方法或函数。让我们看一个带有python约定的显式方法的例子:

def fubar(x):
    self.x = x

class C:
    frob = fubar

现在fubar函数不能工作了,因为它假定self是一个全局变量(在frob中也是如此)。另一种方法是使用替换的全局作用域(其中self是对象)执行方法。

隐式方法是

def fubar(x)
    myX = x

class C:
    frob = fubar

这意味着myX将被解释为fubar(以及frob)中的局部变量。这里的替代方案是使用替换的局部作用域执行方法,该作用域在调用之间保留,但这将消除方法局部变量的可能性。

然而,目前的情况很好:

 def fubar(self, x)
     self.x = x

 class C:
     frob = fubar

在这里,当作为方法调用时,frob将通过self参数接收它所调用的对象,fubar仍然可以以对象作为参数调用并且工作相同(我认为它与C.frob相同)。

与前面提到的所有其他原因一样,它允许更容易地访问被覆盖的方法;你可以调用Class.some_method(inst)。

举个例子说明它的用处:

class C1(object):
    def __init__(self):
         print "C1 init"

class C2(C1):
    def __init__(self): #overrides C1.__init__
        print "C2 init"
        C1.__init__(self) #but we still want C1 to init the class too
>>> C2()
"C2 init"
"C1 init"

"self"关键字保存类的引用,这取决于你是否想要使用它,但如果你注意到,每当你在python中创建一个新方法时,python会自动为你写self关键字。如果你做了一些研究,你会注意到,如果你在一个类中创建了两个方法,并试图在另一个方法中调用一个方法,它不会识别方法,除非你添加self(类的引用)。

class testA:
def __init__(self):
    print('ads')
def m1(self):
    print('method 1')
    self.m2()
def m2(self):
    print('method 2')

以下代码抛出无法解决的引用错误。

class testA:
def __init__(self):
    print('ads')
def m1(self):
    print('method 1')
    m2()  #throws unresolvable reference error as class does not know if m2 exist in class scope
def m2(self):
    print('method 2')

现在让我们看看下面的例子

class testA:
def __init__(self):
    print('ads')
def m1(self):
    print('method 1')
def m2():
    print('method 2')

现在,当您创建类testA的对象时,您可以像这样使用类对象调用方法m1(),因为方法m1()包含了self关键字

obj = testA()
obj.m1()

但是如果你想调用方法m2(),因为它没有自我引用,所以你可以像下面这样直接使用类名调用m2()

testA.m2()

但是要坚持使用self关键字,因为它还有其他好处,比如在内部创建全局变量等等。

这个参数的使用,通常称为self并不难理解,为什么它是必要的呢?或者为什么要明确地提到它?我想,对于大多数查找这个问题的用户来说,这是一个更大的问题,如果不是,他们在继续学习python时肯定会有同样的问题。我建议他们阅读以下几篇博客:

1:使用自我解释

注意,它不是关键字。

每个类方法(包括init)的第一个参数始终是对类当前实例的引用。按照惯例,这个参数总是命名为self。在init方法中,self指向新创建的对象;在其他类方法中,它引用被调用方法的实例。例如,下面的代码与上面的代码相同。

2:为什么我们要这样做,为什么我们不能像Java那样把它作为一个参数,而是用一个关键字来代替

我想补充的另一件事是,一个可选的self参数允许我在一个类中声明静态方法,不写self。

代码示例:

class MyClass():
    def staticMethod():
        print "This is a static method"

    def objectMethod(self):
        print "This is an object method which needs an instance of a class, and that is what self refers to"

PS:这只适用于Python 3.x。

在以前的版本中,您必须显式地添加@staticmethod装饰器,否则self参数是必须的。

它是对类实例对象的显式引用。