首页 > 其他 > 详细

第12关类和对象

时间:2019-03-25 23:27:27      阅读:194      评论:0      收藏:0      [点我收藏+]

在这之前,先要和大家讲一讲两种编程思维:从【面向过程】编程到【面向对象】编程。

因为我们还没开始学习【类与对象】的相关知识,为了方便理解,我们举个生活化的例子。比如我们现在接到的一个需求是:做一道西红柿炒鸡蛋。

第一种方法是:自己按照炒菜的步骤亲手制作一道西红柿炒鸡蛋。

第二种方法是:制作一台炒菜机器人,然后告诉机器人做一道西红柿炒鸡蛋。

在这里,我们直接面对的是机器人,而非炒菜的过程,所以这里机器人就是我们面对的对象,这种解决问题的方法就叫做【面向对象】编程。

【面向过程】编程主要用到的是“函数”知识,将每个过程步骤打包成函数,再依次调用,还记得我们项目二用到的几个函数吗?
 而【面向对象】编程主要用到的是“类和对象”知识,这也是我们这两关的学习目标。
虽然中文命名代码一样可以运行,但这种方式在编程世界里【并不规范】,属于非主流。所以大家在实际编程的时候,还是务必用英文取名:
 1 #直接运行即可
 2 
 3 变量1 = 2019
 4 变量2 = 中国梦
 5 
 6 def 打印变量():
 7 # 虽然可以中文命名,但括号依旧要用英文
 8     print(变量1)
 9     print(变量2)
10 
11 def 两倍放大(数据):
12     数据 =  数据 * 2
13     return 数据
14 
15 打印变量()
16 print(两倍放大(1000))
 

 

# 用英文取名才是规范的    
var1 = 2019
var2 = 中国梦

def print_var():
    print(var1)
    print(var2)

def double_num(num):
    num =  num * 2
    return num

print_var()
print(double_num(1000))

 输出

2019
中国梦
2000

类是一个函数包,理解【类】最简单的方式:【类】是一个函数包。类中可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量。

我们来看看类中是如何放置函数和变量的。

类中可以放置函数和变量

就像我们可以用def语句来自定义一个函数,我们用class语句来自定义一个类。

 语法:创建一个名为“ClassName”的类,类名一般首字母要大写,(): 不能丢   
class ClassName():
# 如定义一个名为‘狗‘的类,可以写成class Dog():
    # 规范:class语句后续的代码块要缩进  
    def function1():
    # 定义类中的函数1

既然【类】是一个函数包,所以一个类中可以放置一堆函数,就像这样:(如前文所说,以下例子会用中文取名)

class 类A():
    def 函数1():
        print(报道!我是类A的第一个方法!)
    def 函数2():
        print(报道!我是类A的第二个方法!)
    def 函数3():
        print(报道!我是类A的第三个方法!)

在类中被定义的函数被称为类的【方法】,描述的是这个类能做什么。我们使用类名.函数名()的格式,就可以让类的方法运行起来。让我们来试一试:

class 类A():
    def 函数1():
        print(报道!我是类A的第一个方法!)
    def 函数2():
        print(报道!我是类A的第二个方法!)
    def 函数3():
        print(报道!我是类A的第三个方法!)

类A.函数1()
类A.函数2()
类A.函数3()
报道!我是类A的第一个方法!
报道!我是类A的第二个方法!
报道!我是类A的第三个方法!

除了函数外,在类中还可以放置一堆变量,就像这样:

class 类A():
    变量1 = 100
    变量2 = -5.83
    变量3 = abc

在类中被定义的变量被称为类的【属性】。使用类名.变量名的格式,可以把类中的属性的值提取出来。让我们来试一试:(这里需要用print语句,把取出的数值打印到屏幕上)

class 类A():
    变量1 = 100
    变量2 = -5.83
    变量3 = abc

# 这里需要用print语句,才能把提取出的数值打印到屏幕上
print(类A.变量1)
print(类A.变量2)
print(类A.变量3)

不过类中的属性(变量)也不是不能改变,使用类名.变量名的格式,可以让我们在类的外面,增加或修改类的属性:

class 类A():
    变量1 = 100
    变量2 = -5.83
    变量3 = abc

类A.变量1 = 99
类A.变量4 = 新增一个变量

print(类A.变量1)
print(类A.变量4)

当类中放置了函数和变量,类就有了方法和属性

下面我们来制作一个最简单的,既有方法又有属性的类:

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    # 以上为类属性
    def 打招呼():
        print(主人你好!)
    def 卖萌():
        print(主人,求抱抱!)
    def 生气():
        print(主人,我要报警了!)
    # 以上为类方法

我们可以把类属性打印出来,也可以调用类方法。请运行代码体验一下这个“智能机器人”:

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    def 打招呼():
        print(主人你好!)
    def 卖萌():
        print(主人,求抱抱!)
    def 生气():
        print(主人,我要报警了!)

print(把类的属性打印出来:)
print(智能机器人.胸围)
print(智能机器人.腰围)
print(智能机器人.腰围)

智能机器人.打招呼()
智能机器人.卖萌()
智能机器人.生气()

现在你你应该知道使用类的属性和方法了吧?

下面我们来做个练习,请为机器人再添加一个方法智能机器人.奔跑(),当运行这个方法的时候,屏幕上会打印出一串字符:我快乐地奔跑、奔跑……哎呦喂!撞墙了。

# 请补全代码    
class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    def 打招呼():
        print(主人你好!)
    def 卖萌():
        print(主人,求抱抱!)
    def 生气():
        print(主人,我要报警了!)
    def 奔跑():
        print(我快乐的奔跑,奔跑,,,,,,,哎呦喂!撞墙了。)
智能机器人.奔跑()

再来做个练习,为机器人再添加一个属性智商 = 200,当运行print(智能机器人.智商)这个的时候,屏幕上会打印出200。请补全代码。

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    智商 = 200

    def 打招呼():
        print(主人你好!)
    def 卖萌():
        print(主人,求抱抱!)
    def 生气():
        print(主人,我要报警了!)

print(智能机器人.智商)

干得不错哟~在这里,我们为了让代码更直观,一般会把类中的函数和函数之间换行隔开,这不影响代码运行。

看到这里,你可能会有有点疑惑,类方法也是函数,那和我们之前学的单独定义函数有什么区别吗?

们两者最大的区别,一个是它的调用格式:类.函数名()函数名()多了一个【类.】,但更重要的是,“类”中的函数可以利用“类”中的变量(也就是类方法可以调用类属性)。

技术分享图片

这里新出现的@classmethod是声明了下面的函数是类方法,为什么要这么写呢?这就是我们接下来要讲的

类方法和类属性可以组合

什么意思呢?我们来看一个例子:下面的类中有两个变量和一个函数。请直接运行体验一下。然后请猜猜函数1的功能是什么

# 请直接运行体验代码

class 类A():
    变量1 = 100
    变量2 = 200

    @classmethod
    def 函数1(cls):
        print(cls.变量1)
        print(cls.变量2)

类A.函数1()

函数1()的功能是:把类中的变量1和变量2打印出来。

在这里,为了把类中的变量传递给类中的函数,我们需要用到3个特定格式:

① 第一个格式@classmethod的中文意思就是“类方法”,@classmethod声明了函数1是类方法,这样才能允许函数1使用类属性中的数据。

② 第二个格式cls的意思是class的缩写。如果类方法函数1想使用类属性(也就是类中的变量),就要写上cls函数1的第一个参数,也就是把这个类作为参数传给自己,这样就能被允许使用类中的数据。

③ 第三个格式是cls.变量。类方法想使用类属性的时候,需要在这些变量名称前加上cls.

这就好比类方法之间的约法三章,所以但凡有任何格式错误都会报错。

另外,当类中的函数【不需要】用到类中的变量时,就不要用@classmethodclscls.三处格式,否则就是占着茅坑不拉屎,终端也会给你报错。(没错,就是这么傲娇~)

# 请运行代码,报错后,修改格式到正确的样式就能运行通过

class 类A():
    变量1 = 100
    变量2 = 200
    
    @classmethod
    def 函数1():
        print(我不需要使用类属性。)

类A.函数1()

让我们牢记正确格式。当格式正确后,我们就可以开心的玩耍了

‘‘‘【正确案例】‘‘‘

class 类A():
    变量1 = 100
    变量2 = 200
    
    def 函数1():  # 【不需要】使用类属性
        print(我不需要使用类属性。)
    
    @classmethod
    def 函数2(cls):  # 【需要】使用类属性
        print(cls.变量1)
        print(cls.变量2)

类A.函数1()
类A.函数2()

让我们做一个练习,为刚才的智能机器人,再写一个自报三围的类方法,调用方式是智能机器人.自报三围(),调用该类方法的终端显示效果如下:

主人,我的三围是:
胸围:33
腰围:44
臀围:55
哈哈哈哈哈,下面粗上面细,我长得像个圆锥
class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    
    def 打招呼():
        print(主人你好!)
    
    def 卖萌():
        print(主人,求抱抱!)

    def 生气():
        print(主人,我要报警了!)
    
    def 自报三围 ()
        print(主人,我的三围是:)


智能机器人.自报三围()

老师的答案是这样的:

# 请直接运行体验代码

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    
    def 打招呼():
        print(主人你好!)
    
    def 卖萌():
        print(主人,求抱抱!)
    
    def 生气():
        print(主人,我要报警了!)
        
    @classmethod
    def 自报三围(cls):
        print(主人,我的三围是:)
        print(胸围: + str(cls.胸围))
        print(腰围: + str(cls.腰围))
        print(臀围: + str(cls.臀围))
        print(哈哈哈哈哈,下面粗上面细,我长得像个圆锥。)

智能机器人.自报三围()

这个练习中,类方法“自报三围”通过cls的格式,取得了类属性“胸围、腰围、臀围”的值并打印了出来。这个过程中,数据是按箭头方向流转的:

在实际编程中,通过【数据流转】,我们还能让类为我们做更多事情。

给类方法传参

首先,既然函数能传递参数,类方法能不能传递参数呢?答案是肯定的。我们谈一谈如何给类方法传参。

类方法仅使用外部参数

我们可以给函数传递参数被函数内部使用,就像这样:

def add_100(num):
    sum = num + 100
    print(计算结果如下:)
    print(sum)

num = 1
add_100(num)
计算结果如下:
101

类方法和函数类似,也可以传递参数。我们把上面的函数"收编",改造成类中的方法,代码会变成这样:

# 请直接运行并体验代码效果
class 加100类():
    def 加100函数(参数):
        总和 = 参数 + 100
        print(计算结果如下:)
        print(总和)

参数 = 1
加100类.加100函数(参数)

这里的加100类()中的加100函数,只使用了外部的参数,没有使用类属性,所以格式上不需要@classmethodcls

让我们做个练习。这里有一个函数,运行起来可以“念诗”:

一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]

def 念诗函数(参数):
    for i in 参数:
        print(i)

念诗函数(一首诗)

请你把上面的代码改造成类方法:

首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]
class 念诗类():
    def 念诗函数(参数):
        for i in 参数:
            print(i)

念诗类.念诗函数(一首诗)

和函数不同的是,类方法还可以利用类属性作为参数,也就是从类的内部给自己传递参数。

类方法仅使用内部参数

课堂开始的时候有一个智能机器人的例题,就是从类的内部给自己传递参数。我们运行代码体验一下:

# 请直接运行并体验代码效果
class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55

    @classmethod
    def 自报三围(cls):
        print(主人,我的三围是:)
        print(胸围: + str(cls.胸围))
        print(腰围: + str(cls.腰围))
        print(臀围: + str(cls.臀围))
        print(哈哈哈哈哈,下面粗上面细,我长得像个圆锥。)

智能机器人.自报三围()

我们来做个练习,这是刚才的念诗类方法

一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]

class 念诗类():
    def 念诗函数(参数):
        for i in 参数:
            print(i)

念诗类.念诗函数(一首诗)

然后我们把变量一首诗从类的外部放到类的内部,请你调整代码,让念诗类()能够从内部获得参数,实现和之前相同的念诗功能。提示:可参考上述机器人的例子

class 念诗类():
    一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]

    @classmethod
    def 念诗函数(cls):
        for i in cls.一首诗:
            print(i)


念诗类.念诗函数()

当然,类方法可以同时使用内部参数和外部参数,我们接着看。

老师写了一个加100类

# 请直接运行并体验代码效果
class 加100类():
    变量 = 100
    
    @classmethod
    def 加100函数(cls,参数):
        总和 = cls.变量 + 参数
        print(加100函数计算结果如下:)
        print(总和)

参数 = int(input(请输入一个整数:))
加100类.加100函数(参数)

这个类一共接受了两个参数,一个是用户输入的外部参数,另一个是cls这个内部参数

另外提一下,当类方法要使用多个外部参数时,我们要多预设几个参数位置。比如:

# 请直接运行并体验代码效果
class 加100类():
    变量 = 100
    
    @classmethod
    def 加100函数(cls,参数1,参数2,参数3):
        总和 = cls.变量 + 参数1 + 参数2 + 参数3
        print(加100函数计算结果如下:)
        print(总和)

参数1 = int(input(请输入一个整数:))
参数2 = int(input(请输入一个整数:))
参数3 = int(input(请输入一个整数:))

加100类.加100函数(参数1,参数2,参数3)

我们再做个练习吧~

你的目标是:改造这段念诗代码,让念诗类.念诗函数()可以接受外部参数,且运行效果应如下:

念给张三的诗:
《卜算子》
我住长江头,
君住长江尾。
日日思君不见君,
共饮长江水。
class 念诗类():
    一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]
    
    @classmethod
    def 念诗函数(cls,参数1):
        print(念给+参数1+的诗:)
        for i in cls.一首诗:
            print(i)
           


念诗类.念诗函数(张三)

到这里,给类方法传参的知识全部讲完了,让我们总结一下

技术分享图片

 

 

接下来我们要讲解一下,如何增加/修改类属性。

 
 
增加/修改类属性

 有两种途径来增加或修改类属性。一种是从内部,用类方法去增加/修改;另一种是从外部,用类.变量 = xx直接增加/修改类属性。

从外部增加/修改属性

我们先看看从外部直接增加/修改类属性:

# 请直接运行并体验代码效果

class 类A():
    pass


类A.变量1 = 100
print(类A.变量1)

类A()是一个空类(里面的pass语句代表“什么都不做”),利用类A.变量1,我们在外部给类A()添加了一个类属性变量1,然后使用print语句把类属性打印了出来。

我们来做个练习,请你观察以下代码,然后判断它的运行结果

变量1 = 15
#这是类外部的变量1
变量2 = abc

class 类A():
    变量1 = 100
    #这是类属性变量1

变量1 = 类A.变量1
类A.变量2 = 变量2

print(类A.变量1)
print(类A.变量2)
我们要区分两个变量,虽然名字相同,但是类外部的变量1和类属性变量1是两个不同的变量。变量1 = 类A.变量1是把类属性100重新赋值给了类外部的变量1,类属性变量1的值没有改变,还是100。

 而类A.变量2 = 变量2,是为类A增加了一个类属性变量2,它的值等于外部的变量2也就是abc

我们再做一个练习。请你先体验以下代码,然后接下来会有一道题目。

# 请直接运行并体验代码效果

class 类():
    @classmethod
    def 打印类属性(cls):
        print(cls.变量)

类.变量 = input(请输入字符串:)
类.打印类属性()

刚才你运行的代码,先利用input函数从外部接收了一个字符串,并通过赋值的方式保存为了类属性类.变量。然后利用类方法类.打印类属性()打印出了这个外部输入的字符串。

接下来,我们要做一个“幸运数翻倍”小程序,这个程序能接收外部输入的幸运数字,然后翻888倍打印出来。程序运行效果如下

你的幸运数是多少?请输入一个整数。(用户输入:66)
好的,我把它存了起来,然后翻了888倍还给你:58608

class 幸运():
    @classmethod
    def 好运翻倍(cls):
        
        cls.a=str(cls.幸运数*888)
        print(好的,我把它存了起来,然后翻了888倍还给你:+cls.a)
幸运.幸运数 = int(input(你的幸运数是多少?请输入一个整数:))
幸运.好运翻倍()

这是自己写的,老师写的如下


class 幸运():
    @classmethod
    def 好运翻倍(cls):
        print(‘好的,我把它存了起来,然后翻了888倍还给你:‘ + str(cls.幸运数*888))
        # 或者这样写也可以:
        # print(‘好的,我把它存了起来,然后翻了888倍还给你:%d‘ % (cls.幸运数*888))

幸运.幸运数 = int(input(‘你的幸运数是多少?请输入一个整数。‘))
幸运.好运翻倍()

到这里,如何从【类的外部】增加/修改类属性就比较清楚了,让我们再看看如何从【类的内部】增加/修改类属性

从内部增加/修改属性

我们来体验一段代码:让类方法直接增加/修改类属性:

 

# 请直接运行体验代码

class 类():
    @classmethod
    def 增加类属性(cls):
        cls.变量 = input(请随意输入字符串:)

类.增加类属性()

print(打印新增的类属性:)
print(类.变量)

可以发现,我们直接通过类方法类.增加并打印类属性()接收外部输入的字符串,然后新增为类属性

掌握这个技巧后,我们再做一个练习,这里是“给张三的诗”代码

class 念诗类():
    一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]
    
    @classmethod
    def 念诗函数(cls,参数):
        print(念给+ 参数 +的诗:)
        for i in cls.一首诗:
            print(i)

念诗类.念诗函数(张三)

现在希望你能改良这段程序,令它的运行效果如下:

请输入你想给谁念诗:(用户输入“张三”)
念给张三的诗:
《卜算子》
我住长江头,
君住长江尾。
日日思君不见君,
共饮长江水。
class 念诗类():
    一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]
    
    @classmethod
    def 念诗函数(cls):
        a = input(请输入你想给谁念诗:)
        print(念给+a+的诗)
        for i in cls.一首诗:
            print(i)

念诗类.念诗函数()

老师写的如下

class 念诗类():
    一首诗 = [《卜算子》,我住长江头,,君住长江尾。,日日思君不见君,,共饮长江水。]
    
    @classmethod
    def 念诗函数(cls):
        cls.接收人 = input(请输入你想给谁念诗:)
        print(念给+ cls.接收人 +的诗:)
        for i in cls.一首诗:
            print(i)

念诗类.念诗函数()

到这里,如何从类的内部和外部增加/修改类属性就学习完毕了:

现在是人人都会写代码的时代,作为班主任的你也不例外,为了录入学生的成绩,你自己写了一段代码:

# 请直接运行体验代码

class 成绩单():
    @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input(请输入学生姓名:)
        cls.语文_成绩 = int(input(请输入语文成绩:))

成绩单.录入成绩单()
print(成绩单.学生姓名 + 的成绩单如下:)
print(语文成绩:+ str(成绩单.语文_成绩))

我们现在要做的第一步改装是,请写出一个类方法成绩单.打印成绩单(),代替那两句print语句,起到同样的运行效果。

class 成绩单():
    @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input(请输入学生姓名:)
        cls.语文_成绩 = int(input(请输入语文成绩:))
    @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + 的成绩单如下:)
        print(语文成绩:+ str(cls.语文_成绩))

成绩单.录入成绩单()
成绩单.打印成绩单()

请继续改良class 成绩单(),让它可以录入和打印的信息多一项“数学成绩”。要求改良后的代码运行效果是这样的:

class 成绩单():
    @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input(请输入学生姓名:)
        cls.语文_成绩 = int(input(请输入语文成绩:))
        cls.数学_成绩= int(input(请输入数学成绩:))
    @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + 的成绩单如下:)
        print(语文成绩:+ str(cls.语文_成绩))
        print(数学成绩:+ str(cls.数学_成绩))
成绩单.录入成绩单()
成绩单.打印成绩单()

让我们再接再厉,继续改良class 成绩单(),让它多一个类方法成绩单.打印平均分()。要求改良后的代码运行效果是这样的

class 成绩单():
    @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input(请输入学生姓名:)
        cls.语文_成绩 = int(input(请输入语文成绩:))
        cls.数学_成绩 = int(input(请输入数学成绩:))
        
    @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + 的成绩单如下:)
        print(语文成绩:+ str(cls.语文_成绩))
        print(数学成绩:+ str(cls.数学_成绩))
              
    @classmethod
    def 打印平均分(cls):
        print(int(cls.语文_成绩+cls.数学_成绩)/2)

成绩单.录入成绩单()
成绩单.打印成绩单()
成绩单.打印平均分()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第12关类和对象

原文:https://www.cnblogs.com/zhuyanze/p/10595714.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!