原文链接:http://www.juzicode.com/archives/561
计算机语言中“类”几乎是所有高级语言的必备选项,类的概念如其字面意义一样,表示的是一类具有相同特性的事物。比如一个Student类,它有一些相同的属性,比如名字,性别,学号,成绩,电话号码等等,还可以定义一些方法获取名字、性别等信息,修改成绩、电话等信息。相对于类是一个抽象出来的概念,而一个具体的学生对应的就是一个实例(instance)。
实际上前面学习过的int,str,list,tuple等等“数据类型”都是某一种类型的class(类),用type(X)可以得到X的类型,从显示的结果可以看出所有的这些“数据类型”都是一种class。以float数据为例,type()得到的类型为<class ‘float’>。
>>> a = 3.14
>>> type(a)
<class 'float'>
1 类的定义
类的定义用class关键字进行定义,所有这个类的实体内容都是在这个class的下一层缩进中:
class 类名称():
类实体内容
下面是一个简单的例子,定义一个名称为Student的类:
class Student():
def __init__(self,name,id):
self.name = name
self.id = id
这个类中定义了一个__init__()的方法(在面向对象编程中,函数称为方法),在这个方法中,定义了self.name和self.id的2个属性(在面向对象编程中,成员变量称为属性),Student类的属性前面要用“self.”来进行约束。注意这里的__init__()方法括号中的入参self是必须的,其他name、id是传入的参数,在__init__()调用之后name、id就不存在了,所以这里要用self.name和self.id将它们保存下来。
接下来实例化一个Student对象,并且打印出它的类型和属性:
s1 = Student('wangwu',20200505) #实例化对象
print('s1类型:',type(s1)) #打印其类型
print('s1的name:',s1.name)
print('s1的id:',s1.id)
s1类型: <class '__main__.Student'>
s1的name: wangwu
s1的id: 20200505
实例化一个对象的方法:“对象名称=类名(a,b)”,其他a,b是__init__()方法中除去self之外的参数,在实例化一个对象时就会默认调用这个类的__init__()方法,在__init__()方法的第一个语句用print()打印一行提示,从打印可以看出在实例化对象时就调用了该方法。
class Student():
def __init__(self,name,id):
print('实例化对象......')
self.name = name
self.id = id
实例化对象......
s1类型: <class '__main__.Student'>
s1的name: wangwu
s1的id: 20200505
【注意:】__init__()的前后都有2个下划线!
当然在一个class中__init__()方法也不是必须的,看一个例子:
class Student():
def set_name_id(self,name,id):
self.name = name
self.id = id
s1 = Student()
s1.set_name_id('wangwu',20200505)
print('s1类型:',type(s1))
print('s1的name:',s1.name)
print('s1的id:',s1.id)
s1类型: <class '__main__.Student'>
s1的name: wangwu
s1的id: 20200505
在这个例子中就没有__init__()方法,在s1 = Student()实例化了一个s1的对象后,要显式地调用set_name_id()方法,对其name和id进行初始化。对比__init__()方法,这种方式要显得更麻烦些。
2 方法
在class中除了__init__()方法,还可以定义其他的方法,也是用def定义,入参的第一个使用self,其他的入参可以根据需要是0到多个。还是以上面的Student为例,再定义2个方法获取类的name和id属性。
class Student():
def __init__(self,name,id):
print('实例化对象......')
self.name = name
self.id = id
def get_name(self):
return self.name
def get_id(self):
return self.id
s1 = Student('wangwu',20200505)
print('s1类型:',type(s1))
print('s1的name:',s1.get_name())
print('s1的id:',s1.get_id())
-----欢迎来到www.juzicode.com
-----公众号: juzicode/桔子code
实例化对象......
s1类型: <class '__main__.Student'>
s1的name: wangwu
s1的id: 20200505
在这个例子中,定义了get_name()和get_id()的2种方法,返回了类的name和id属性,定义get_name()和get_id()的方式跟函数定义是一样的,都是用def进行定义,不过默认都将self作为第1个入参。可以使用self来访问整个class中的所有属性,比如get_name()方法就使用了self.name的属性,即使比如get_name()并没有在入参中传入self.name。从这个例子也可以看出slef.name的作用范围是整个class中。
方法的调用方式:“实例名称.方法()”,注意在使用属性和方法时都是用实例名称,而不是使用类的名称,因为只有实例化的对象才由具体的属性和方法,一个抽象的类是不存在属性和方法的。
同样,方法也是在整个class中都是可见的,还是这个例子,定义了一个新的方法get_name_id(),将调用get_name()和get_id()这2种方法,当然在这个例子中返回name和id这么使用显得有点多余,不过这里的主要目的是要看下class内方法的相互调用关系。
s1 = Student('wangwu',20200505) #实例化对象
print('s1类型:',type(s1)) #打印其类型
print('s1的name:',s1.name)
print('s1的id:',s1.id)
s1类型: <class '__main__.Student'>
s1的name: wangwu
s1的id: 20200505
3 添加属性
在前面的例子中大都是在__init__()方法中初始化它的属性,其实可以像set_name_id()的例子中那样调用方法添加属性:
class Student():
def set_name_id(self,name,id):
self.name = name
self.id = id
s1 = Student()
s1.set_name_id('wangwu',20200505)
还可以在对象完成实例化后用“对象名称.新属性”的方法添加属性,下面的例子是在对象已经完成实例化之后这种方法添加一个score属性:
class Student():
def __init__(self,name,id):
print('实例化对象......')
self.name = name
self.id = id
def get_name(self):
return self.name
def get_id(self):
return self.id
s1 = Student('wangwu',20200505)
print('s1的name:',s1.get_name())
print('s1的id :',s1.get_id())
s1.score = 95 # 用“对象名称.新属性”的方法添加属性
print('s1的score:',s1.score)
s1的name: wangwu
s1的id : 20200505
s1的score: 95
虽然这种添加属性的方式也是合法的,但是在使用的时候要千万小心,因为在__init__()方法中没有初始化过该属性,如果其他的方法中使用了该属性,但是没有在实例化对象后添加过该属性就会导致抛异常,我们在这个类的基础上再添加一个方法get_score():
class Student():
def __init__(self,name,id):
print('实例化对象......')
self.name = name
self.id = id
def get_name(self):
return self.name
def get_id(self):
return self.id
def get_score(self):
return self.score
s1 = Student('wangwu',20200505)
print('s1的name:',s1.get_name())
print('s1的id :',s1.get_id())
s1.score = 95
print('s1的score:',s1.get_score()) #get_score()方法中用到了score属性。
s1的name: wangwu
s1的id : 20200505
s1的score: 95
在上面的例子中get_score()方法中用到了score属性,是因为在调用get_score()方法前正好用s1.score = 95增加了个score的属性,一切看起来还ok。但是如果注释掉s1.score = 95,就会导致抛AttributeError异常了!