python基础知识(五)

(六)类与对象

类:某一类具有共同属性和特性的事物或者说是一个抽象的描述,比如说大佬类,你就是大佬类里面具体的一个实例。类一般包含属性和方法

(1)类的语法:

class 类名:

       类属性

       类方法/类函数

类属性:放在类里面的变量值,相当于我们自己在类里面定义的属性

类方法/类函数:写在类里面的函数,类里面的方法都必须带self这个参数,self代表实例本身,我们可以理解为这是一个实例方法的标志。

例如,写一个男朋友的类:

 1 class BoyFriend:
 2     # 类属性
 3     height = 175
 4     weight = 130
 5     money = "500万"
 6 
 7     # 类函数
 8     def cooking(self):
 9         print ("男朋友要会做饭")
10 
11     def earn(self):
12         print ("男朋友的月薪是3万")
13 
14 
15 bf = BoyFriend () # 实例
16 print (bf.money)

打印出来的结果是:500万

注:类属性和类方法不是一定要同时写在类里面,可以只写类属性,也可以只写类方法。

 

(2)类名的规范

由数字字母下划线组成,不能以数字开头,首字母大写,驼峰命名(例:TestCase);

 

(3)实例/对象:具体的一个例子

a、创建实例/对象:类名()

实例具有类里面所有的属性和方法的使用权,实例可以调用类里面的任意属性和任意方法/函数;

 

b、调用属性

实例.属性名

 

c、调用方法/函数名

实例.方法名()

实例.函数名()

 例如:

 1 class Teacher:
 2     name = "xiaozhu"
 3     age = "20"
 4 
 5     def coding(self):  # 实例方法
 6         print (self.name + "会敲代码")
 7 
 8     def cooking(self):  # 实例方法
 9         print (self.name + "会做饭")
10 
11     @classmethod  # 类方法
12     def swimming(cls):
13         print ("会游泳")
14 
15     @staticmethod
16     def sing():  # 普通函数
17         print ("会唱歌")
18 
19 
20 t = Teacher ()  # 实例
21 t.coding ()

 打印出来的结果是:xiaozhu会敲代码

但是这里就存在一个问题,所有的人都叫xiaozhu,年龄都是20岁,在接下来会讲到一个初始化函数,可以解决这个问题~👇

 

d、类里面的方法

类里面的方法分为三种:

实例方法:意味着这个方法只能实例来调用,一般不传动态参数和关键字参数,必须要创建实例来进行调用 类名()

隐式传递:t=Teacher()

显示传递(不建议使用):Teacher.coding(t)

 

类方法:@classmethod  要传一个cls参数

类方法调用:Teacher.swimming()    t.swimming()

 

静态方法:@staticmethod 不需要传参数 

静态方法调用: Teacher.swimming()  t.sing()

 

注:实例方法(self)、类方法(cls)、静态方法(普通方法),实例和类名都可以直接调用;

      类方法和静态方法可以直接类名.方法名来进行调用,实例方法必须要创建实例才可以进行调用 类名()。

不同点:静态方法和类方法不可以调用类里面的属性值,如果要参数的话就需要自己传参数进去;

 

e、什么时候去定义为静态方法和类方法?(运用场景)

当你的某个函数与其他的类函数、类属性没有任何关系,就可以定义为静态方法和类方法,这样做的目的仅仅是为了方便调用。

 

(4)初始化函数

语法:def __init__(self,参数1,参数2,参数3.....参数n):

用法:def __init__(self,a,b):

             self.a=a

             self.b=b

注:

a、初始化里面做的是初始化操作,可以带参数也可以不带参数;

b、跟普通函数一样,可以带默认参数;

c、初始化函数里面可以有赋值好了的属性值;

d、每次创造一个实例,需要传递跟初始化函数参数个数一致的值;

e、每个实例都自动调用初始化函数,需要传递对应的参数;

f、初始化参数的写法要注意,怎么把参数赋值给self.参数名,参数名字不一定要一致,但是赋值要正确;

g、初始化函数没有返回值。

 

例如:

 

 1 class Student:
 2     def __init__(self, name, age):  # 实例方法
 3         self.name = name
 4         self.age = age
 5 
 6     def coding(self,lines,language='python'):  # 实例方法
 7         print (self.name + "会敲{0}代码,敲了{1}行代码".format(language,lines))
 8 
 9     def cooking(self,*args):  # 实例方法
10         for item in args:
11           print (self.name + "会做{0}".format(item))
12 
13     @classmethod  # 类方法
14     def swimming(cls):
15         print ("会游泳")
16 
17     @staticmethod  # 类方法
18     def sing():
19         print ("会唱歌")
20 
21 
22 t1 = Student ("xiaozhu", "20")
23 t1.coding(10000)
24 t1.cooking('蛋炒饭','辣椒炒肉','麻辣小龙虾')

 

打印出来的结果是:xiaozhu会敲python代码,敲了10000行代码

                           xiaozhu会做蛋炒饭

                           xiaozhu会做辣椒炒肉

                           xiaozhu会做麻辣小龙虾

初始化函数的使用场景:想用的时候就用;如果某个属性值是多个函数共用的,就可以用初始化函数。

 

(5)继承

a、继承是我们类里面学习的一个重要的概念

继承的定义:

被继承的类---->父类

获得继承的类---->子类

子类继承父类所有函数及其属性的操作就称之为类的继承

 

b、继承的语法

class 子类名称(父类名称):

        这里可以写自己需要的属性或者函数

 

注:

1、继承的类是否要用到初始化函数,要看有没有从父类里面继承了初始化函数;

2、父类有的,子类继承以后可以直接拿过来用;

3、子类里面的函数与父类里面的函数名重复的时候,子类的实例会优先调用子类的函数,如果子类没有的话再调用父类的。

 

 

c、类的重写和拓展

重写:子类对父类里面的部分属性或者是函数,想重新定义进行修改,就可以进行重写;

重写的特点:

1、子类的属性名称可以与父类一致,创建新的子类对应的实例,会调用最新改写的子类属性;

2、子类的函数名称可以与父类一致,创建新的子类对应的实例,会调用最新改写的子类函数。

 

拓展:新增父类里面没有的属性和类方法,只属于子类专有的方法和属性。

 

d、多继承

python支持多继承,可以同时继承多个类(了解),多继承如果子类继承了两个类,那么子类就会具有这两个父类的属性和方法,如果两个父类具有同名的方法时,子类调用函数就会采取就近原则,初始化函数也包括在内;

例如:

 1 class RobotOne:
 2     def __init__(self, year, name):
 3         self.year = year
 4         self.name = name
 5 
 6     def walking_on_ground(self):
 7         print (self.name + "只能在平地上行走")
 8 
 9     def robot_info(self):
10         print ("{0}年生产的机器人{1}是中国研发出来的".format (self.year, self.name))
11 
12 
13 class RobotTwo ():
14     def __init__(self,name):
15         self.name=name
16 
17     def walking_on_ground(self):
18         print (self.name + "在平地上平稳的行走")
19 
20     def walking_avoid_block(self):  # 拓展
21         print (self.name + "可以避开障碍物")
22 
23 
24 #
25 # t = RobotTwo ("1888", "xiaozhu")
26 # t.robot_info ()
27 # t.walking_on_ground ()
28 class RobotThree (RobotOne, RobotTwo):
29     def jump(self):
30         print (self.name + "可以跳")
31 
32 
33 r = RobotThree ("1999", 'xiaozhu')
34 r.jump()
35 r.walking_on_ground()

打印出来的结果是:

xiaozhu可以跳
xiaozhu只能在平地上行走

 

e、超继承

如果你重写了父类里面的一个方法,又想调用父类里面的一些方法,就可以用超继承,我们到时候在单元测试的时候就会用到这个操作,不用去重写复制代码,这样就可以做到更多的继承(了解会用) 

例如:

 1 class RobotOne:
 2     def __init__(self, year, name):
 3         self.year = year
 4         self.name = name
 5 
 6     def walking_on_ground(self):
 7         print (self.name + "只能在平地上行走")
 8 
 9     def robot_info(self):
10         print ("{0}年生产的机器人{1}是中国研发出来的".format (self.year, self.name))
11 
12 
13 class RobotTwo (RobotOne):  # 继承
14 
15     def walking_on_ground(self):
16         print (self.name + "在平地上平稳的行走")
17 
18     def walking_avoid_block(self):  # 拓展
19         # 在子类的函数里面调用父类的函数
20         self.robot_info ()
21         print (self.name + "可以避开障碍物")
22 
23 
24 t = RobotTwo ("1888", "xiaozhu")
25 t.robot_info ()
26 t.walking_on_ground ()

打印出来的结果是:

1888年生产的机器人xiaozhu是中国研发出来的
xiaozhu在平地上平稳的行走

 

超继承的例子🌰:

超继承的关键字super,超继承使用场景:想用父类的方法,但是又不想重新写的话就可以用超继承。

 1 # 超继承
 2 class MathMethod:
 3     def __init__(self, a, b):
 4         self.a = a
 5         self.b = b
 6 
 7     def add(self):
 8         print ("我是父类的加法",self.a + self.b)
 9 
10     def sub(self):
11         return self.a - self.b
12 
13 
14 class MathMethod_1 (MathMethod):
15 
16     def divide(self):  # 拓展
17         return self.a / self.b
18 
19     def add(self):  # 重写
20         super(MathMethod_1,self).add() # 超继承
21         print ("我是子类的加法",self.a + self.b + 10)
22 
23 MathMethod_1(4,3).add()

打印出来的结果是:

我是父类的加法 7
我是子类的加法 17

 

 

👉做点习题:

 1 No.1  创建一个名为 User 的类:
 2 1)其中包含属性 first_name 和 last_name,还有用户简介通常会存储的其他几个属性,均是自定义, 请放在初始化函数里面。
 3 2)在类 User 中定义一个名为 describe_user()的方法,它打印用户信息摘要;
 4 3)再定义一个名为 greet_user()的方法,它向用户发出个性化的问候;
 5 请创建3个不同用户的实例,并对每个实例都调用上述两个方法
 6 
 7 
 8 
 9 
10 No.2  定义一个学生类。
11 1)有下面的类属性: 1 姓名 2 年龄 3 成绩(语文,数学,英语)[每课成绩的类型为整数] ,均放在初始化函数里面。
12 2)类方法:
13    a)获取学生的姓名:get_name() 返回类型:str
14    b)获取学生的年龄:get_age() 返回类型:int
15    c) 返回3门科目中最高的分数 get_course() 返回类型:int
16 写好类以后,可以用以下的数据来测试下:
17 zm = Student('zhangming',20,[77,88,99])
以上的题目可以自行练习,如果需要参考答案私我呀~(如果阁下足够厉害,自动忽略这句话)
 
 
(6)debug
代码出错的时候,哪行代码出错就打在哪一行代码上
 
 
 
以上,第五部分到此结束~ 
 posted on 2019-04-10 16:36  许小猪  阅读(415)  评论(0编辑  收藏  举报