想想这个例子:

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


当前回答

我很惊讶居然没人提起Lua。Lua也使用“self”变量,但是可以省略,但仍然使用。c++对'this'做了同样的处理。我不认为有任何理由必须在每个函数中声明“self”,但你仍然可以像使用lua和c++一样使用它。对于一门以简洁为傲的语言来说,它要求你声明self变量是很奇怪的。

其他回答

首先,self是一个传统的名字,你可以用其他任何东西(连贯)来代替它。

它引用对象本身,因此当您使用它时,您声明.name和.age是您将要创建的Student对象(注意,不是Student类)的属性。

class Student:
    #called each time you create a new Student instance
    def __init__(self,name,age): #special method to initialize
        self.name=name
        self.age=age

    def __str__(self): #special method called for example when you use print
        return "Student %s is %s years old" %(self.name,self.age)

    def call(self, msg): #silly example for custom method
        return ("Hey, %s! "+msg) %self.name

#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)

#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self

#you can modify attributes, like when alice ages
alice.age=20
print alice

代码在这里

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

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中创建一个新方法时,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”这个词指的是一个类的实例

class foo:
      def __init__(self, num1, num2):
             self.n1 = num1 #now in this it will make the perimeter num1 and num2 access across the whole class
             self.n2 = num2
      def add(self):
             return self.n1 + self.n2 # if we had not written self then if would throw an error that n1 and n2 is not defined and we have to include self in the function's perimeter to access it's variables

它的使用类似于Java中this关键字的使用,即给出对当前对象的引用。