想想这个例子:

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时肯定会有同样的问题。我建议他们阅读以下几篇博客:

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参数是必须的。

其他回答

Self是对对象本身的引用,因此,它们是相同的。 Python方法不是在对象本身的上下文中调用的。 self在Python中可以用来处理自定义对象模型或其他东西。

看看下面的例子,它清楚地解释了self的目的

class Restaurant(object):  
    bankrupt = False

    def open_branch(self):
        if not self.bankrupt:
           print("branch opened")

#create instance1
>>> x = Restaurant()
>>> x.bankrupt
False

#create instance2
>>> y = Restaurant()
>>> y.bankrupt = True   
>>> y.bankrupt
True

>>> x.bankrupt
False  

Self用于/需要用于区分实例。

来源:python中的self变量解释- Pythontips

"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参数中。

因此,对象的数据被绑定到对象上。下面是一个示例,说明您可能希望如何可视化每个对象的数据。注意“self”是如何被对象名称替换的。我并不是说下面这个示例图是完全准确的,但希望它能在可视化self的使用方面起到一定的作用。

对象被传递到self参数中,这样对象就可以保存自己的数据。

Although this may not be wholly accurate, think of the process of instantiating an object like this: When an object is made it uses the class as a template for its own data and methods. Without passing it's own name into the self parameter, the attributes and methods in the class would remain as a general template and would not be referenced to (belong to) the object. So by passing the object's name into the self parameter it means that if 100 objects are instantiated from the one class, they can all keep track of their own data and methods.

如下图所示:

从医生那里,

方法的特殊之处在于实例对象是作为函数的第一个参数传递的。在我们的例子中,调用x.f()完全等价于MyClass.f(x)。一般来说,调用带有n个参数列表的方法相当于调用带有参数列表的相应函数,该参数列表是通过在第一个参数之前插入方法的实例对象创建的。

在此之前的相关片段,

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

x = 我的类()