我们先来看一段代码:
class A():
def function1(text):
print(text);
def function2(self,text):
print(text);
定义一个类A,A中有两个方法,一个不带self关键字的方法function1,一个带self关键字的方法function2,我们调用一下
//根据我们语言学习的经验,我们知道调用一个类的方法首先要实例化这个类
//什么叫实例化,就是我们定义了一个类,但仅仅是告诉计算机,有这么一个东西,但计算机并没有生成这个东西,
//只有实例化,计算机才在内存中开辟一段空间,然后生成一个类扔到这个空间去,
//所以我们首先实例化
a = A();
//调用A类的function2
a.function2("python"); //语句(1)
A.function2(a,"python");//语句(2)
a.function1("python");
运行结果:
python
python
报错:TypeError: sing() missing 1 required positional argument: 'one'
我们发现,语句(1)(2)的执行结果相同,且编译器未报错。语句(3)报错
我们先看语句(1),语句(1)中,我们定义的function2方法中明明含有两个参数self和text,但我们调用的时候仅仅给一个参数(text)赋值,并没有给self传入值,但是一样调用。
再看语句(2),我们直接使用A.function2来调用A的方法,按照正常的实例化不应该是使用A的实例化对象a来调用方法吗?这时候,我们已经隐约知道self的作用了。
self关键字,其实就是起到实例化本身的作用。
在语句(1)中,我们的a,已经是A的实例化了, 所以不需要再给self关键字传入值来实例化。
在语句(2)中,虽然A不是实例化,仅仅是一个类名,但是我们传入了一个A的实例化a,(function2(a,“python”))。
我们用自然语言来解释这俩个语句:
a.function2("python");//我们实例化一个A的对象a,a要调用function2
//检测到a已经是A的实例化对象,所以不需要再实例化A了, self关键字不需要新建一个A的实例了
// self关键字将自动绑定实例
A.function2(a,"python");//A不是一个实例化对象,所以我们必须要对A进行实例化,a是A的实例化对象,我们把a传入
//代表实例化A,同时绑定这个实例化
a.function1("python");//我新建一个A的实例a,想用a调用function1方法,但是,虽然我有a的实例,但是我没有将这个实例传入
//所以报错
因此,我们总结一下,self关键字是必要的,你可以调用方法的时候,可以不填这个self参数,填不填这个参数是你的事,但是创建方法的时候,第一个参数必须是self,不写就是不行,它起到一个将实例化自身,并绑定实例化的作用。
我们在实验一下,在方法里的属性加上self关键字
x = 5;
class A():
def defineValue(self):
self.x = 10;
def putSelf(self):
print(x);
a = A();
a.putSelf();
输出结果:
5
我们发现,方法putSelf调用的是外部的x,而不是自身的self.x,因为只有带self的属性,才是自身的属性,不带self的,那就是外部属性了。