想想这个例子:

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 Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

我们需要一个计算长度的方法。如果我们想在类中定义它会是什么样子呢?

    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

当我们将它定义为全局方法/函数时,它应该是什么样子?

def length_global(vector):
    return math.sqrt(vector.x ** 2 + vector.y ** 2)

所以整个结构保持不变。我怎样才能利用这个呢?假设我们还没有为Vector类编写length方法,我们可以这样做:

Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0

这是因为length_global的第一个参数可以重用为length_new中的self参数。如果没有显式的自我,这是不可能的。


另一种理解显式self需求的方法是查看Python在哪里添加了一些语法糖。当你记住的时候,基本上,一个电话就像

v_instance.length()

在内部转化为

Vector.length(v_instance)

很容易看出自我在哪里。实际上你不用在Python中编写实例方法;你所写的是类方法,它必须以一个实例作为第一个参数。因此,必须显式地将实例参数放置在某个位置。

其他回答

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

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

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

objectA是这个类的一个实例。

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

ClassA.methodA(objectA, arg1, arg2)

self变量引用对象本身。

我想说,至少对于Python, self参数可以被认为是一个占位符。 看看这个:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

p1 = Person("John", 36)

print(p1.name)
print(p1.age)

Self在这里,还有很多其他的被用作存储name值的方法。然而,在此之后,我们使用p1将其分配给我们正在使用的类。然后当我们打印它时,我们使用相同的p1关键字。

希望这对Python有所帮助!

“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

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

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