加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

笨办法学Python 习题 40: 模块、类、对象

发布时间:2020-12-17 17:01:36 所属栏目:Python 来源:网络整理
导读:Python 是一种“面向对象编程语言 (Object Orien te d Programming Language)” 。这个说法的意思是说,Python 里边有一种叫做 class 的结构,通过它你可以用一种特殊的方式构造你的软件。通过使用class (类),你可以让你的程序架构更为整齐,使用起来也会更

Python 是一种“面向对象编程语言 (Object Oriented Programming Language)” 。这个说法的意思是说,Python 里边有一种叫做 class 的结构,通过它你可以用一种特殊的方式构造你的软件。通过使用class (类),你可以让你的程序架构更为整齐,使用起来也会更为干净--至少理论上应该是这样的。

现在我要教你的是面向对象编程的起步知识,我会用你学过的知识向你介绍面向对象编程、类、以及对象。问题是变相对象编程(简称 OOP )本身就是个奇怪的东西,你只有努力去弄懂这一章的内容,好好写代码,然后到下一章节的习题,我就能把 OOP 像钉钉子一样钉到你脑子里了。

现在就开始吧。

模块和字典差不多

你知道怎样创建和使用字典这个数据类型,这是一种将一种东西对应到另外一种的方式。这意味着如果你有一个字典,它里边有一个叫 ‘ apple’ 的 key ,而你要从中取值的话,你需要这样做:

mystuff?=?{'apple':?"I?AM?APPLES!"}
print?mystuff['apple']

记住这个“从 Y 获取 X” 的概念,现在再来看看模块 (module) ,你已经创建和使用过一些模块了,你已经了解了它们的一些属性:

????1. 模组是包含函数和变量的 Python 文件。

????2. 你可以 import 这个文件。

????3. 然后你可以使用 ‘ .’ 操作符访问到模组中的函数和变量。

假如说我有一个模块名字叫 mystuff.py 并且在里边放了个叫做 apple 的函数,就像这样:

#?this?goes?in?mystuff.py
def?apple():
????print?"I?AM?APPLES!"

接下来我就可以用 import 来调用这个模块,并且访问到 apple 函数:

import?mystuff
mystuff.apple()

我还可以放一个叫做 tangerine 的变量到模块里边:

def?apple():
????print?"I?AM?APPLES!"
#?this?is?just?a?variable
tangerine?=?"Living?reflection?of?a?dream"

一样的我还是可以访问到这个变量:

import?mystuff
mystuff.apple()
print?mystuff.tangerine

回到字典的概念,你会发现这和字典的使用方式有点相似,只不过语法不同而已,我们来比一比:

mystuff['apple']?#?get?apple?from?dict
mystuff.apple()?#?get?apple?from?the?module
mystuff.tangerine?#?same?thing,?it's?just?a?variable

也就是说, Python 里边有这么一个通用的模式:

????1. 拿一个类似 key=value 风格的数据容器

????2. 通过 key 的名称获取其中的 value

对于字典来说,?key 是一个字符串获得值的语法是 [key]?。对于模块来说,?key 是函数或者变量的名称,而语法是 .key 。除了这个,它们基本上就没什么区别了。

类和模块差不多

模块还可以用一种方法去理解:你可以把它们当做一种特殊的字典,通过它们你可以储存一些 Python代码,而你可以通过 ‘ .’ 操作符访问到这些代码。 Python 还有另外一种代码结构用来实现类似的目的,那就是 类 (class) ,通过类,你可以把一组函数和数据放到一个容器中,从而用 ‘ .’ 操作符访问到它们。

如果我要用创建 mystuff 模块的方法来创建一个类,那么方法大致是这样的:

class?MyStuff(object):
????def?__init__(self):
????????self.tangerine?=?"And?now?a?thousand?years?between"
????
????def?apple(self):
????????print?"I?AM?CLASSY?APPLES!"

这个和模块比起来有些复杂,确实,比起模块来,这里的确做了很多事情,不过你应该能大致看出来,这段代码差不多就是模拟了一个名字叫 MyStuff 的迷你模块,里边有一个叫做 apple() 的函数,难懂的恐怕是?__init__()?函数,还有就是设置 tangerine 变量时用了 self.tangerine 这样的语法。

使用类而非模块的原因如下:你可以拿着上面这个类,重复创建出很多出来,哪怕是一次一百万个,它们也不会互相干涉到。而对于模块来说,当你一次 import 之后,整个程序里就只有这么一份内容,只有鼓捣得很深才能弄点花样出来。

不过在弄懂这个之前,你要先理解“对象( object )”是什么东西,以及如何使用 MyStuff 达到类似import mystuff 实现的结果。

对象相当于迷你版的 import

如果说类和迷你模块差不多,那么对于类来说,也必然有一个类似 import 的概念。这个概念名称就是“实例 (instance)”?。这只是一种故作高深的叫法而已,它的意思其实是“创建”。当你将一个类“实例化”以后,你就得到了一个 对象 (object) 。

实现实例化的方法,就是像调用函数一样地调用一个类 :

thing?=?MyStuff()
thing.apple()
print?thing.tangerine

第一行代码就是“实例化”操作,这和调用函数很相似。然而,当你进行实例化操作时, Python 在背后做了一系列的工作,这里我针对上面的代码详细解释一下:

????1. Python 看到了 MyStuff() 并且知道了它是你定义过的一个类。

????2. Python 创建了一个空的对象,里边包含了你在类中用 def 创建的所有函数。

????3. 然后 Python 回去检查你是不是在里边创建了一个 __init__ 魔法函数,如果你有创建,它就会调用这个函数,从而对你的空对象实现了初始化。

????4. 在 MyStuff 中的 __init__ 函数里,我们有一个多余的函数叫做 self ,这就是 Python 为我们创建的空对象,而我可以对它进行类似模块、字典等的操作,为它设置一些变量进去。

????5. 在这里,我把 self.tangerine 设成了一段歌词,这样我就初始化了该对象。

????6. 最后 Python 将这个新建的对象赋给一个叫 thing 的变量,以供后面使用。

这就是当你像调用函数一样调用类的时候, Python 完成这个“迷你 import” 的过程。记住这不是拿来一个类就直接用,而是将类当做一个“蓝图”,然后用它创建和这个类有相同属性的拷贝。

提醒你一点,我的解释和 Python 的实际原理还是有一点小小的出入,只不过在这里,基于你现有的关于模块的知识,我也暂时只能这么解释了。事实上类和对象和模组是完全不同的东西。如果我实实在在地跟你讲的话,我大概会说出下面的这些东西:

?????6?1 类就像一种蓝图、或者一种预定义的东西,通过它可以创建新的迷你模块。

?????6?1 实例化的过程相当于你创建了这么一个迷你模块,而且同时 import 了它。

?????6?1 结果生成的迷你模块就是一个对象,你可以将它赋予一个变量并进行后续操作。

而通过这一系列的操作,类和对象和模块已经很不同了,所以这里的内容只是为了让你理解类的概念而已。

从东西里获取东西

现在我有三种方法可以从某个东西里获取它的内容:

#?dict?style
mystuff['apples']
#?module?style
mystuff.apples()
print?mystuff.tangerine
#?class?style
thing?=?MyStuff()
thing.apples()
print?thing.tangerine

第一个类的例子

你应该开始注意到这三种 key=value 的容器类数据,而且有一些问题要问。先别问,下面一讲会让你了解面向对象编程的一些专有词汇。在这一节里,我只要求你写代码并让它运行起来,有了经验才能继续前进。

#?-*-?coding:utf-8?-*-
class?Song(object):?#创建类
????def?__init__(self,lyrics):??#创建方法
????????self.lyrics?=?lyrics
????def?sing_me_a_song(self):???#创建方法
????????for?line?in?self.lyrics:
????????????print?line
#添加htppy_baby属性
happy_baby?=?Song(["Happy?birthday?to?you",???????????????????"I?dont't?want?to?get?sued",???????????????????"So?I'll?stop?right?there"])
#添加bulls_on_parde属性
bulls_on_parde?=?Song(["They?rally?around?the?family",??????????????????????"With?pockets?full?of?shells"])
happy_baby.sing_me_a_song()
bulls_on_parde.sing_me_a_song()

结果:

Happy?birthday?to?you
I?dont't?want?to?get?sued
So?I'll?stop?right?there
They?rally?around?the?family
With?pockets?full?of?shells

加分习题

1.使用这种方式写更多的歌进去,确定自己懂得了传入的歌词是一个字符串列表。

i_love_you?=?Song(["I?love?you",???????????????????"I?hate?you"])
i_love_you.sing_me_a_song()

2. 将歌词放到另一个的变量里边,然后再类里边使用这一个新定义的变量。

class?Song(object):?#创建类
????def?__init__(self,lyrics):??#创建方法
????????self.lyrics?=?lyrics
????def?sing_you_a_song(self):???#创建方法
????????for?line?in?self.lyrics:
????????????print?line

3. 试着看能不能给它加些新功能,不知道怎么做也没关系,只要试着去做也行,弄坏了也没关系,反正它也不会疼。

4. 在网上搜索一下“ object oriented programming” (中文:面向对象编程),给自己洗洗脑。弄懂也没关系,其实里边有一半的东西对我来说也是没有意义的。

常见问题回答

为什么创建 __init__ 或者别的类函数时需要多加一个 self 变量?

如果你不加 self , cheese = 'Frank' 这样的代码意义就不明确了,它指的既可能是实例的 cheese 属性,或者一个叫做 cheese 的局部变量。有了 self.cheese ='Frank' 你就清楚地知道了这指的是实例的属性 self.cheese 。


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读