当前位置:   article > 正文

python类和对象基础教程_python 类 对象 教程

python 类 对象 教程
本教程的
​​​​​​ 思维导图

1.类和对象

1.1什么是类?什么又是对象?

类和对象都是面向对象中的重要概念。面向对象是一种编程思想,即按照真实世界的思维方式构建软件系统。例如,在真实世界的校园里有学生和老师,学生有学号、姓名、所在班级等属性(数据),还有学习、提问、吃饭和走路等动作(方法)。如果我们要开发一个校园管理系统,那么在构建软件系统时,也会有学生和老师等“类”,张同学、李同学是学生类的个体,被称为“对象”,“对象”也被称为“实例”   类就是一个模板,具有相同属性和行为(方法)的对象的集合,对象是类的具象化,而类是对象的抽象化。类是模板,比如修房子的图纸,比如制作蛋挞的模型一样,有了这个模版,我们便可以创建真实的模的着看得见的实例,就是对象 万物皆对象!!!

通过小汽车类实例化不同的车(对象)

1.2定义类

Python中的数据类型都是类,我们可以自定义类,即创建一种新的数据类型。Python中类的定义语法格式如图所示

以上两种方式皆可,其中object是超类,也就是类的根,所有的类都继承自object类,可以不用写,我们便定义了一个小汽车的类,类名叫做Car  ,class是关键字  pass语句是用于维持程序的结构的完整性,当我们还不知道些什么的时候可以使用paa 这样程序也不会报错 当我们想好如何写的时候再写上相应的逻辑实现即可 ,使用pass便不会出现语法上的错误,起到占位的作用

1.3创建对象

类相当于一个模板,依据这样的模板来创建对象,就是类的实例化,所以对象也被称为“实例“,如下图所示,可以直观的理解类和对象的关系。

定义好啦Car类,然后我们创建了Car类的对象,通过类名加小括号创建了对象,然后赋值给变量car,此时系统会自动调用类的构造方法,用于初始化对象,比如创建对象的属性并进行赋值,该方法在创建对象后,系统自动执行类的构造方法,我们显示的写出来 但每个类都内置的有一个构造方法用于初始化对象 __init__(self,参数1,参数2,...),当我们创建的对象不需要的时候,便要对这个对象进行销毁,释放空间,在python中销毁对象由python垃圾回收器在后台释放对象,不需要我们手动的释放,当然我们想要手动释放也是可以的 析构方法 __del__(self),进行删除对象

2.类的成员

在类体中包含的类的成员如下图所示:

成员变量也被称为数据成员,保存了类或对象的数据。例如,学生的姓名和学号。

构造方法是一种特殊的函数,用于初始化类的成员变量。

成员方法是在类中定义的函数。

属性是对类进行封装而提供的特殊方法。

问:实例变量和实例方法与类变量和类方法有什么区别呢?

答:实例变量和实例方法属于对象,通过对象.变量名或者方法名进行使用,而类方法和类变量是通过类进行使用类名.名字,当然也可以通过对象.名字调用,因为类里面的公有东西对象都可以访问调用,python中类里面的对象默认是公有的,有些成员如果设置为私有的我们在类外便不能通过对象直接调用

2.1实例变量

实例变量就是对象个体特有的“数据”,例如狗狗的名称和年龄等等,我们来写一个Dog类,然后实例化狗类对象dog1,通过Dog类的构造方法为dog这个实例进行属性的添加并且初始化赋值,dog对象有名字,和年纪和性别这三个个属性,性别我们默认为雄性,如下所示:

__init__(self,参数列表)类是构造方法,是内置方法,当我们实例出一个对象的时候系统自动会执行,我们在创建对象dog的时候,执行构造方法并给其属性赋值,我们没有传递sex,默认为雄性,自己也可以指定性别 注意构造方法的第一个参数self,就是对象的引用,大白话就是执行构造方法的时候,把这个对象传进去了,self.name等价于dog.name可以这样理解,python中是把该对象和self进行了绑定,self就是dog,dog就是self,这样理解就好

2.2构造方法

类中的__init__()方法是一个非常特殊的方法,用来创建和初始化实例变量,这种方法就是“构造方法”。在定义__init__()方法时,它的第1个参数应该是self,之后的参数用来初始化实例变量。调用构造方法时不需要传入self参数,

代码示例:

  1. #定义类
  2. class Dog(object):
  3. #类体
  4. def __init__(self,name,age,sex="雄性"):
  5. self.name=name
  6. self.age=age
  7. self.sex=sex
  8. dog=Dog("小花",2,sex="雌性")#实例化Car类的对象,并初始化属性
  9. print("我叫{},我现在{}啦,我是{}滴".format(dog.name,dog.age,dog.sex))
'
运行

2.3实例方法

实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法,定义实例方法时,它的第1个参数也应该是self,这会将当前实例与该方法绑定起来,这也说明该方法属于实例。在调用方法时不需要传入self,类似于构造方法,举个例子,我们来理解一下,比如说我创建了dog对象,他现在有了名字年纪还有性别,我再给她写个跑的方法,和说的方法,让狗狗跑起来,会汪汪叫,这便是实例方法,具体如下所示:

  1. #定义类
  2. class Dog(object):
  3. #类体
  4. def __init__(self,name,age,sex="雄性"):
  5. self.name=name
  6. self.age=age
  7. self.sex=sex
  8. #定义实例方法,跑起来让狗狗
  9. def run(self):
  10. print("{}跑起来了".format(self.name))
  11. #定义实例方法,说 让狗狗叫起来
  12. def speak(self):
  13. print("{}在汪汪叫".format(self.name))
  14. dog1=Dog("小花",2,sex="雌性")#实例化Car类的对象,并初始化属性
  15. dog2=Dog("小黑",3)
  16. print("我叫{},我现在{}啦,我是{}滴".format(dog.name,dog.age,dog.sex))
  17. dog1.run()
  18. dog1.speak()
  19. dog2.run()
  20. dog2.speak()

2.4类变量

类变量是属于类的变量,不属于单个对象,例如,有一个Account(银行账户)类,它有三个成员变量:amount(账户金额)、interest_rate (利率)和owner(账户名)。amount和owner对于每一个账户都是不同的,而interest_rate对于所有账户都是相同的。amount和owners是实例变量,interest_rate是所有账户实例共享的变量,它属于类,被称为“类变量”类变量的示例代码如下:

  1. #定义类Account
  2. class Account:
  3. interest_rate=0.987#类变量利率
  4. def __init__(self,owner,amount):
  5. self.owner=owner#创建并初始化实例变量owner
  6. self.amount=amount#创建并初始化实例变量amount
  7. account=Account("rose",50000000)
  8. print("账户名:{}".format(account.owner))
  9. print("账户余额:{}".format(account.amount))
  10. print("利率:{}".format(Account.interest_rate))
'
运行

2.5类方法

类方法与类变量类似,属于类,不属于个体实例。在定义类方法时,它的第1个参数不是self,而是类本身,如下所示:

  1. #定义类Account
  2. class Account:
  3. interest_rate=0.987#类变量利率
  4. def __init__(self,owner,amount):
  5. self.owner=owner#创建并初始化实例变量owner
  6. self.amount=amount#创建并初始化实例变量amount
  7. #定义类方法
  8. @classmethod
  9. def interest_by(cls,mat):#cls表示自身类也就是Account
  10. return cls.interest_rate*mat#cls也可以换成Account
  11. #account=Account("rose",50000000)
  12. # print("账户名:{}".format(account.owner))
  13. # print("账户余额:{}".format(account.amount))
  14. # print("利率:{}".format(Account.interest_rate))
  15. print(Account.interest_by(50000))
  16. ac1=Account("jike",80000000)
  17. print(ac1.interest_by(50000))
'
运行

3.封装性

封装性是面向对象重要的基本特性之一。封装隐藏了对象的内部细节,只保留有限的对外接口,外部调用者不用关心对象的内部细节,使得操作对象变得简单。例如,一台计算机内部极其复杂,有主板、CPU、硬盘和内存等,而一般人不需要了解它的内部细节。计算机制造商用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,使用计算机就变得非常简单。

3.1私有变量

为了防止外部调用者随意存取类的内部数据(成员变量),内部数据(成员变量)会被封装为“私有变量”。外部调用者只能通过方法调用私有变量。在默认情况下,Python中的变量是公有的,可以在类的外部访问它们。如果想让它们成为私有变量,则在变量前加上双下画线(__)即可

示例代码如下:

  1. #定义类Account
  2. class Account:
  3. __interest_rate=0.987#类变量利率
  4. def __init__(self,owner,amount):
  5. self.owner=owner#创建并初始化实例变量owner
  6. self.__amount=amount#创建并初始化实例私有变量amount
  7. def desc(self):
  8. print("账户名:{} 金额:{} 利率:{}".format(self.owner,self.__amount,self.__interest_rate))
  9. account=Account("daday",8000000)
  10. account.desc()
'
运行

注意,在类的外部不可以访问私有变量,如下所示:

如果我们要在类外面访问类的私有成员,我们可以在私有成员前面加_类名即可,如下所示:

  1. #定义类Account
  2. class Account:
  3. __interest_rate=0.987#类变量利率
  4. def __init__(self,owner,amount):
  5. self.owner=owner#创建并初始化实例变量owner
  6. self.__amount=amount#创建并初始化实例私有变量amount
  7. def desc(self):
  8. print("账户名:{} 金额:{} 利率:{}".format(self.owner,self.__amount,self.__interest_rate))
  9. account=Account("daday",8000000)
  10. account.desc()
  11. print("账户金额{}".format(account._Account__amount))
  12. print("利率为{}".format(Account._Account__interest_rate))
'
运行

3.2私有方法

私有方法与私有变量的封装是类似的,在方法前加上双下画线(__)就是私有方法了。示例代码如下:

  1. #定义类Account
  2. class Account:
  3. __interest_rate=0.987#类变量利率
  4. def __init__(self,owner,amount):
  5. self.owner=owner#创建并初始化实例变量owner
  6. self.__amount=amount#创建并初始化实例私有变量amount
  7. #定义普通方法
  8. def desc(self):
  9. print(self.__get_info())
  10. #定义私有方法
  11. def __get_info(self):
  12. return "账户为:{},金额有:{},利率是:{}".format(self.owner,self.__amount,self.__interest_rate)
  13. account=Account("daday",8000000)
  14. account.desc()
  15. #account.__get_info()
'
运行

注意在类外调用__get_info()方法的时候,会报错,如果想要调用的话,需要在方法名前面加__类名,两条下划线加类名即可,如下所示:

  1. #定义类Account
  2. class Account:
  3. __interest_rate=0.987#类变量利率
  4. def __init__(self,owner,amount):
  5. self.owner=owner#创建并初始化实例变量owner
  6. self.__amount=amount#创建并初始化实例私有变量amount
  7. #定义普通方法
  8. def desc(self):
  9. print(self.__get_info())
  10. #定义私有方法
  11. def __get_info(self):
  12. return "账户为:{},金额有:{},利率是:{}".format(self.owner,self.__amount,self.__interest_rate)
  13. account=Account("daday",8000000)
  14. account.desc()
  15. print(account._Account__get_info())
'
运行

3.3使用属性

为了实现对象的封装,在一个类中不应该有公有的成员变量,这些成员变量应该被设计为私有的,然后通过公有的set (赋值)和get(取值)方法访问。使用set和get方法进行封装,示例代码如下

  1. class Dog:
  2. def __init__(self,name,age,sex="雄性"):
  3. self.name=name
  4. self.__age=age#给私有属性age赋值
  5. self.sex=sex
  6. #实例方法
  7. def run(self):
  8. print("{}在跑",format(self.name))
  9. #给age设置get方法,返回age
  10. def get_age(self):
  11. return self.__age
  12. #修改私有属性age的set方法
  13. def set_age(self,new_age):
  14. self.__age=new_age
  15. #实例化狗狗对象,并初始化赋值给狗狗对象
  16. dog=Dog("小黄",2,sex="雌性")
  17. print("{}是的年纪为{}岁,是{}滴".format(dog.name,dog.get_age(),dog.sex))
  18. dog.set_age(3)#修改狗狗的年纪
  19. print("修改后的{}的年纪为{}岁".format(dog.name,dog.get_age()))
'
运行

上述示例中,当外部调用者通过两个公有方法访问被封装的私有成员的时候,会比较麻烦,我们可以修改一下,类属性(property)便是解决这种的,我们可以在类中定义属性,属性替代get()和set()方法,这样调用就会比较简单修改上述代码,如下所示:

  1. class Dog:
  2. def __init__(self,name,age,sex="雄性"):
  3. self.name=name
  4. self.age=age#给私有属性age赋值
  5. self.sex=sex
  6. #实例方法
  7. def run(self):
  8. print("{}在跑",format(self.name))
  9. @property
  10. def age(self):#替代get_age(self)
  11. return self.__age
  12. @age.setter
  13. def age(self,new_age):#替代set_age(self,new_age)
  14. self.__age=new_age
  15. #实例化狗狗对象,并初始化赋值给狗狗对象
  16. dog=Dog("小黄",2,sex="雌性")
  17. print("{}是的年纪为{}岁,是{}滴".format(dog.name,dog.age,dog.sex))#通过属性取值访问形式为对象.属性
  18. dog.age=3#修改狗狗的年纪,替代dog.set_age(3)
  19. print("修改后的{}的年纪为{}岁".format(dog.name,dog.age))
'
运行

属性的本质就是方法,在方法前面加一个装饰器,使得方法变为了属性 属性使用起来类似于公有变量,可以在赋值符号(=)左边或者右边,在左边为赋值,在右边为取值

4.继承性

继承性也是面向对象重要的基本特性之一,在现实世界中继承关系无处不在。例如猫与动物之间的关系:猫是一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对象中动物是一般类,被称为“父类”;猫是特殊类,被称为“子类”。特殊类拥有一般类的全部数据和操作,可称之为子类继承父类

4.1python中的继承

在Python中声明子类继承父类,语法很简单,定义类时在类的后面使用一对小括号指定它的父类就可以了。下面是动物类继承图

代码如下:

  1. class Animal:
  2. def __init__(self,name):
  3. self.name=name
  4. def print_info(self):
  5. print("动物的名字为{}".format(self.name))
  6. def run(self):
  7. print("动物在跑.....")
  8. class Cat(Animal):#定义子类Cat继承了父类Animal的属性和方法
  9. def __init__(self,name,age):
  10. super().__init__(name)#调用父类的构造方法为其赋值
  11. self.age=age
  12. #实例化子类对象
  13. cat=Cat("小黄",2)
  14. cat.run()#调用父类的方法
  15. cat.print_info()#调用父类的方法
'
运行

子类继承父类的时候,只有父类的公有的变量和方法会被继承给子类,注意在子类的构造方法中调用父类的构造方法的时候,初始化子类实例的成员的时候同时也初始化父类的实例变量,先是初始化父类的,在初始化子类的!!

4.2多继承及方法重写

在Python中,当子类继承多个父类时,如果在多个父类中有相同的成员方法或成员变量,则子类优先继承左边父类中的成员方法或成员变量,从左到右继承级别从高到低,如下:

代码如下所示:

  1. class Teacher:
  2. def __init__(self,name,age,course):
  3. self.name=name
  4. self.age=age
  5. self.course=course
  6. def print_info(self):
  7. print(f"老师的名字是:{self.name} 年纪为:{self.age}岁 教的课程为:{self.course}")
  8. def shangke(self):
  9. print(f"{self.name}正在上{self.course}课")
  10. class Student:
  11. def __init__(self,name,age,gread):
  12. self.name=name
  13. self.age=age
  14. self.gread=gread
  15. def print_info(self):
  16. print(f"学生的名字是{self.name},年纪为:{self.age}岁,读{self.gread}级")
  17. def shangke(self):
  18. print(f"{self.name}正在上课")
  19. class ZhuJiao(Teacher,Student):
  20. def __init__(self,name,age,course,gread,jk):#jk为讲课 gread为年级
  21. super().__init__(name,age,course)#调用teacher类的构造方法实例化属性
  22. self.gread=gread
  23. self.jk=jk
  24. def print_info(self):#重写了父类的方法
  25. print(f"{self.name}今年{self.age}岁了,读{self.gread}在给同学讲{self.jk}课:")
  26. zj=ZhuJiao("小李",20,"数学微积分","大学","数学课程习题")
  27. zj.print_info()
  28. zj.shangke()
'
运行

分析:助教类继承了老师类和学生类分别,在定义助教类的时候添加了自己的讲课属性,继承了来自老师类的和学生类的所有方法和属性,同时重写了父类的print_info()方法,两个父类都有shangke()的方法,助教对象调用shangke()方法的时候,是优先调用左边的父类,也就是调用老师类的shangke()方法

5.多态性

多态性也是面向对象重要的基本特性之一。“多态”指对象可以表现出多种形态。例如,猫、狗、鸭子都属于动物,它们有“叫”和“动”等行为,但是叫的方式不同 比如,小狗是汪汪叫,小猫是喵喵叫,小鸭子是嘎嘎叫。

5.1继承与多态

在多个子类继承父类,并重写父类方法后,这些子类所创建的对象之间就是多态的。这些对象采用不同的方式实现父类方法。示例代码如下:

  1. class Animal:
  2. def speak(self):
  3. print("动物在叫,但不知道是哪种动物再叫...")
  4. class Dog(Animal):
  5. def speak(self):
  6. print("小狗狗在汪汪叫.....")
  7. class Cat(Animal):
  8. def speak(self):
  9. print("小喵咪在喵喵叫.....")
  10. class Duck(Animal):
  11. def speak(self):
  12. print("小鸭子在嘎嘎叫.....")
  13. dog=Dog()
  14. cat=Cat()
  15. duck=Duck()
  16. dog.speak()
  17. cat.speak()
  18. duck.speak()
'
运行

5.2鸭子类型测试与多态

Python的多态性更加灵活,支持鸭子类型测试。鸭子类型测试指:若看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子

由于支持鸭子类型测试,所以Python解释器不检查发生多态的对象是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。

例如,我们设计一个函数start()它接收具有“叫”speak()方法的对象,代码如下:

  1. class Animal:
  2. def speak(self):
  3. print("动物在叫,但不知道是哪种动物再叫...")
  4. class Dog(Animal):
  5. def speak(self):
  6. print("小狗狗在汪汪叫.....")
  7. class Cat(Animal):
  8. def speak(self):
  9. print("小喵咪在喵喵叫.....")
  10. class Duck(Animal):
  11. def speak(self):
  12. print("小鸭子在嘎嘎叫.....")
  13. class Car:
  14. def speak(self):
  15. print("小车嘟嘟嘟叫.......")
  16. def star(obj):#定义一个函数用来接收对象具有speak()方法
  17. obj.speak()
  18. dog=Dog()
  19. cat=Cat()
  20. duck=Duck()
  21. car=Car()
  22. star(dog)
  23. star(cat)
  24. star(duck)
  25. star(car)
'
运行

6.练一练

1 在下列选项中,哪些是类的成员。()

A.成员变量

B.成员方法

C.属性

D.实例变量

2 判断对错:(请在括号内打√或×,√表示正确,×表示错误)

1)在Python中,类具有面向对象的基本特性,即封装性、继承性和多态性。()

2)__init__()方法用来创建和初始化实例变量,这种方法就是“构造方法”。()

3)类方法不需要与实例绑定,需要与类绑定,在定义时它的第1个参数不是self。()

4)实例方法是在类中定义的,它的第1个参数也应该是self,这个过程是将当前实例与该方法绑定起来。()

5)公有成员变量就是在变量前加上两个下画线(__)。()

6)属性是为了替代get()方法和set()方法。()

7)子类继承父类时继承父类中的所有成员变量和方法。()

8)Python中的继承是单继承。()

3 请介绍什么是“鸭子类型”?

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/829572
推荐阅读
相关标签
  

闽ICP备14008679号