为什么python中的函数/方法需要self作为参数?

2024-10-01 17:26:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我能理解为什么局部变量需要它(self.x),但为什么nessecary是函数中的参数?有没有别的东西可以代替我放在那里?在

请尽可能多地用外行的话来解释,我从来没有受过像样的编程教育。在


Tags: 函数self参数编程局部变量地用外行nessecary
3条回答

这就是Python的面向对象编程实现的工作原理——调用一个实例的方法(所谓的绑定方法),并将该实例作为其第一个参数。在

除了实例(self.x)的变量之外,您还可以将其用于其他任何事情,例如,调用另一个方法(self.another_method()),将此实例作为参数完全传递给其他对象(mod.some_function(3, self)),或使用它在该类的超类(return super(ThisClass, self).this_method())中调用此方法。在

你也可以给它取一个完全不同的名字。使用pony代替self也同样有效。但你不应该,因为明显的原因。在

如果你考虑一下,每种编程语言都会这样做——或者至少,像pascal、c++或java这样最常见的语言都会这样做)。但是,在大多数编程语言中,this关键字是假定的,而不是作为参数传递的。考虑一下这些语言中的函数指针:它们与方法指针不同。在

帕斯卡:

function(a: Integer): Integer;

^{pr2}$

后者考虑self指针(是的,它的名称是self,但它是一个隐式指针,类似于c++中的this,而pythonself是显式的)。在

C++:

typedef int (*mytype)(int a);

typedef int Anyclass::(*mytype)(int a);

与Pascal的差异,在C++中,必须指定拥有该方法的类。无论如何,这个方法指针声明声明了一个函数与一个不需要this的函数之间的区别。在

但是Python很认真,就像quichua人对待他们的Ama Suway,Ama Llullay,Ama K'ellay一样

Explicit is better than implicit.

所以,这就是为什么您看到显式地为实例方法和@classmethodself参数(当然必须编写它)(尽管它通常被称为cls,因为它的目的是动态地知道类而不是实例)。Python不假定方法中必须存在thisself关键字(因此,名称空间只有真正的变量-请记住,您不必将它们命名为self或{},尽管这是通常和预期的)。在

最后,如果您得到:

x = AClass.amethod #unbound method

你必须称之为

x(aninstance, param, param2, ..., named=param, named2=param2, ...)

而得到的结果是:

x = anInstance.method #bound method, has `im_self` attribute set to the instance.  

必须称为:

x(param, param2, ..., named=param, named2=param2, ...)

是的,self在参数列表中是显式的,因为它不假定关键字或“后门”必须存在,但在参数列表中不存在,因为每个OOP语言都有语法糖分(奇怪的标准,哈?)。在

默认情况下,在类的命名空间中声明的每个函数都假定其第一个参数将是对该类实例的引用。(其他类型的函数用@classmethod@staticmethod修饰以改变这种假设)这类函数称为方法。按照惯例,Python程序员将第一个参数命名为self,但Python不关心您如何称呼它。调用方法时,必须提供该引用。例如(用self替换为foobar,以证明self不是必需的名称):

class A:
    def __init__(foobar):
        foobar.x = 5

    def somefunc(foobar, y):
        print foobar.x + y

a = A()
print A.somefunc(a, 3)   # Prints 8

Python提供了一些语法糖,通过允许您调用绑定方法而不是函数本身,使对象与调用对象的方法之间的链接更加明显。也就是说,a.somefunc(3)和{}是等价的。在Python术语中,A.somefunc是一个未绑定的方法,因为它在调用时仍然需要一个实例:

^{pr2}$

相反,a.somefunc被称为绑定方法,因为您已经提供了用作第一个参数的实例:

f = a.somefunc
print f(3)

相关问题 更多 >

    热门问题