想想这个例子:

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


当前回答

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

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 )

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

其他回答

The reason you need to use self. is because Python does not use special syntax to refer to instance attributes. Python decided to do methods in a way that makes the instance to which the method belongs be passed automatically, but not received automatically: the first parameter of methods is the instance the method is called on. That makes methods entirely the same as functions, and leaves the actual name to use up to you (although self is the convention, and people will generally frown at you when you use something else.) self is not special to the code, it's just another object.

Python could have done something else to distinguish normal names from attributes -- special syntax like Ruby has, or requiring declarations like C++ and Java do, or perhaps something yet more different -- but it didn't. Python's all for making things explicit, making it obvious what's what, and although it doesn't do it entirely everywhere, it does do it for instance attributes. That's why assigning to an instance attribute needs to know what instance to assign to, and that's why it needs 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参数是必须的。

这是为了遵循Python的禅宗“显式优于隐式”。它实际上是对类对象的引用。例如,在Java和PHP中,它被称为this。

如果user_type_name是你的模型中的一个字段,你可以通过self.user_type_name访问它。

自我是不可避免的。

问题是,self是隐式的还是显式的。 Guido van Rossum解决了这个问题说self必须留下来。

那么自我生活在哪里呢?

如果我们坚持函数式编程,我们就不需要self了。 一旦我们进入Python OOP,我们就会发现自己在那里。

下面是带有方法m1的典型用例类C

class C:
    def m1(self, arg):
        print(self, ' inside')
        pass

ci =C()
print(ci, ' outside')
ci.m1(None)
print(hex(id(ci))) # hex memory address

这个程序将输出:

<__main__.C object at 0x000002B9D79C6CC0>  outside
<__main__.C object at 0x000002B9D79C6CC0>  inside
0x2b9d79c6cc0

self保存类实例的内存地址。 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 )

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