转载自:在路上 » 【整理】Python中:self和__init__的含义 + 为何要有self和__init__
关于self的使用作者给出的错误和正确的例子讲解如下:
如果没有在__init__中初始化对应的实例变量的话,导致后续引用实例变量会出错
如下代码,完整的演示了,如果没有在类Class的最初的__init__函数中,正确的初始化实例变量,则会导致后续没有变量可用,因而出现AttributeError的错误:
看注释
# 注:此处全局的变量名,写成name,只是为了演示而用
# 实际上,好的编程风格,应该写成gName之类的名字,以表示该变量是Global的变量
name = "whole global name";
class Person:
def __init__(self, newPersionName):
# self.name = newPersionName;
# 1.如果此处不写成self.name
# 那么此处的name,只是__init__函数中的局部临时变量name而已
# 和全局中的name,没有半毛钱关系
name = newPersionName;
# 此处只是为了代码演示,而使用了局部变量name,
# 不过需要注意的是,此处很明显,由于接下来的代码也没有利用到此处的局部变量name
# 则就导致了,此处的name变量,实际上被浪费了,根本没有利用到
def sayYourName(self):
# 此处由于找不到实例中的name变量,所以会报错:
# AttributeError: Person instance has no attribute 'name'
print 'My name is %s'%(self.name);
def selfAndInitDemo():
persionInstance = Person("crifan");
persionInstance.sayYourName();
###############################################################################
if __name__=="__main__":
selfAndInitDemo();
相应的正确写法的代码如下:
# 注:此处全局的变量名,写成name,只是为了演示而用
# 实际上,好的编程风格,应该写成gName之类的名字,以表示该变量是Global的变量
name = "whole global name";
class Person:
def __init__(self, newPersionName):
# 此处正确的,通过访问self.name的形式,实现了:
# 1.给实例中,增加了name变量
# 2.并且给name赋了初值,为newPersionName
self.name = newPersionName;
def sayYourName(self):
# 此处由于开始正确的初始化了self对象,使得其中有了name变量,所以此处可以正确访问了name值了,可以正确的输出了:
# My name is crifan
print 'My name is %s'%(self.name);
def selfAndInitDemo():
persionInstance = Person("crifan");
persionInstance.sayYourName();
###############################################################################
if __name__=="__main__":
selfAndInitDemo();
一定注意,self是一个“本身,自己”的意思
init
意义:给对应的类Class本身,去初始化。
支持带参数的类的初始化:
看注释
class Person:
def __init__(self, newPersionName):
# 在开始初始化新的类Class的示例Instance的时候,给对应的,不同的Instance,设置不同的人名(Person name)
self.name = newPersionName
def sayYourName(self):
# 不同的Person的示例,调用同样的方法的时候,说出自己的名字,结果都是对应着自己的,各自不同的名字
print('My name is %s'%(self.name)) # My name is crifan
def initDemo():
persionInstance = Person("crifan")
persionInstance.sayYourName()
###############################################################################
if __name__=="__main__":
initDemo()
其中,就是针对Person这个类,
不同的示例,在初始化的时候,都传递一个对应的参数,这样不同的Person,就都有了自己的不同的名字了。
这个,至少看起来,有点类似于,其他语言中的,传递特定参数去对类进行初始化。
实现类本身相关内容的初始化
当一个Class,稍微复杂一点的时候,或者内部函数需要用得到的时候,往往都需要在,别人实例化你这个类之前,使用你这个类之前,做一些基本的,与自己的类有关的,初始化方面的工作。
而这部分工作,往往就放到__init__函数中去了。
换句话说,你要用人家的类(中的变量和函数)之前,总要给人家一个机会,做点准备工作,然后才能为你服务吧。
这个概念,相对还是很好理解的,就不多赘述。
演示代码就不用了,因为上面的代码,也可以算是这方面的例子了,不同的人,应该有不同的名字,而给不同的人设置不同的名字,也是需要在调用sayYourName之前,就先初始化好的。