想想这个例子:

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,考虑如何在类中调用函数?


当前回答

"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方法不是在对象本身的上下文中调用的。 self在Python中可以用来处理自定义对象模型或其他东西。

假设你有一个类ClassA,它包含一个方法methodA,定义为:

def methodA(self, arg1, arg2):
    # do something

objectA是这个类的一个实例。

现在当objectA。当调用methodA(arg1, arg2)时,python会在内部将其转换为:

ClassA.methodA(objectA, arg1, arg2)

self变量引用对象本身。

我将用不使用类的代码演示:

def state_init(state):
    state['field'] = 'init'

def state_add(state, x):
    state['field'] += x

def state_mult(state, x):
    state['field'] *= x

def state_getField(state):
    return state['field']

myself = {}
state_init(myself)
state_add(myself, 'added')
state_mult(myself, 2)

print( state_getField(myself) )
#--> 'initaddedinitadded'

类只是一种避免始终传递这种“状态”的方法(以及其他一些不错的事情,如初始化、类组合、很少需要的元类,以及支持自定义方法来覆盖操作符)。

现在让我们使用内置的python类机制来演示上面的代码,以展示它们基本上是相同的东西。

class State(object):
    def __init__(self):
        self.field = 'init'
    def add(self, x):
        self.field += x
    def mult(self, x):
        self.field *= x

s = State()
s.add('added')    # self is implicitly passed in
s.mult(2)         # self is implicitly passed in
print( s.field )

[把我的答案从重复的封闭式问题中迁移过来]

这个参数的使用,通常称为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参数是必须的。

与前面提到的所有其他原因一样,它允许更容易地访问被覆盖的方法;你可以调用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"