Exercise 40: 模块,类和对象

原文链接:http://learnpythonthehardway.org/book/ex40.html

(ps:这后面我是感觉翻译越来越有压力了,看官们,自己酌情理解啊,不知所云的请看原文)

       Python是被称为“面向对象编程的语言”。这就是说在Python中存在一个被称作class的数据结构,使用它可以以一种特定的方式去构建你的软件。使用类,可以增加你程序的独立性,这样也可以更简洁的使用它们,至少理论上来说是这样的。

       现在我打算开始教你关于面向对象编程,类以及你已经知道的自动和模块对象。面向对象编程(也称作 OOP)概念对你来说可能十分生疏是目前的主要问题。你首先要简单克服这种不理解的纠结心理,尽可能的去理解我在这里所说的知识,敲代码,在下一节练习中我会做进一步介绍。

       现在我们可以开始了。

模块就像字典一样:

       你知道怎样创建一个字典并使用它,知道它是把一件东西和另一件东西建立映射的一种方式。这就是说如果你有个键值为“apple”的字典,想要得到它对应的值你可以这样做:
mystuff = {'apple' : "I AM APPLES!"}
print mystuff['apple']
在脑海中记住“get X from Y”,然后想想模块的使用。你目前应该创建过一些模板,并且使用过它,你知道它们的大概流程如下:
1.一个带有一些函数或者变量的Python文件。
2.然后你引入这个文件。
3.接着你就可以通过 ’.'(点)操作来使用这个模块中的函数或者变量。
想象一下如果我有一个模块并且命名为 mystuff.py并且在里面放了一个叫 apple 的函数,下面就是模块mystuff.py中的内容:
# 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. Take a key=value style container.
2. Get something out fo it by the key's name.

在字典中,键值是一个字符串使用的语法形式是[key]。在模块中,键值是一个标识符,使用是语法形式是 .key 。除此之外它们基本是一样的。

类就像模块:

       可以把模块看作是一种特殊的字典,这种字典可以存储Python代码,你可以通过 '.' 操作来得到其中的代码。Python 中刚还有另一个结构和模块有类似的作用叫做 class。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__()函数和使用 self.tangerine来初始化 tangerine的值这两块了。
       之所以用类来替代模块是因为:你可以用上面的类来创建许多该类的对象,如果你想的话一次创建几百万个都没问题,并且这些对象之间互不干扰。而模块,当你导入的时候整个项目可以使用的模块的对象只有它一个除非你做了些怪物黑客(you do some monster hacks)。
       在你能够完全理解这些之前,你需要知道 "对象" 是什么,了解 MyStuff 是如何像 mystuff.py 一样工作的。

对象就像小型的导入操作:

       如果类像一个“小型模块”的话,那么在类中可能有一个类似 import 的概念的东西。类中的这个概念叫做“实例”,这种叫法可能比较虚幻和难以理解,更聪明的叫法是“创造” 。当你实例化一个类后得到的东西就成为对象。
       调用一个类的方式就像调用一个函数一样,像这样:
thing = Mystuff()
thing.apple()
print thing.tangerine
       第一行就是“实例化”操作,而且它看起来更像调用一个函数。然而当你调用了该函数Python实际上为你做了一系列相对应的事情。这里我就用Mystuff来解释这个流程:
1、Python查找 Mystuff()发现它是你定义过的一个类。
2、Python 创建了一个带有类中所有使用def定义的函数的空对象。
3、Python然后就会去看看如果你创建了一个“神奇”的__init__函数并且如果有创建的话就会自动调用该函数去初始化你创建的空对象。
4、在Mystuff的__init__函数中有一个特别的变量 self ,它是创建这个空对象过程中Python自动为我创建的一个变量,我可以用它来像一个模块、字典或者其他对象一样设置一个变量的值。
5、在这里,我将 self.tangerine的值设为一首歌的歌词然后我就完成了对这个对象的初始化操作。
6、现在Python就可以使用这个新构造的对象来为我需要使用而定义的 thing 变量来赋值。
       这是当你可以像调用一个函数一样调用一个类最基础的“小型导入”操作。记住它病史直接给你使用这个类,取而代之的是使用这个类作为蓝图来构建一个副本。
       你要记住在你已经知道模块的基础上去让你更好的建立对类的理解其实是有点轻微的错误的方法。 事实上,类和对象的概念某种程度上说和模块是有所偏离的。如果我诚实一点的话,我可能会这样说:
> 类就像一个蓝图或者定义用来创建一个新的小型模块。
> 实例化就是创建这些小型模块同时导入这些模块的过程。
> 创建的这个小型模块就被称为对象,然后你就可以将它赋给某个变量来使用它。
        这样解释后类和对象看起来就和模块非常不同了,这也只是为你更好的理解类这个概念的一种方式。

从事物中得到事物:

目前我知道三种方式来从事物中得到事物:
# dict style
mystuff['apples']

#  module style 
mystuff.apples()
print mystuff.tangerine

# class style 
thing = MyStuff()
thing.apples()
print thing.tangerine

第一个类的示例:

        你应该看到了这三种类似的 key=value 容器类型,而且你可能有一大堆问题想问。先把这些问题放在,因为下面的练习中我打算向你强制灌输关于“面向对象的词汇”。在这次的练习中,我只想要你输入这些代码并让它正确运行,这样你在继续往下学习之前就积累了一些经验。
class Song(object):

	def __init__(self ,lyrics):
		self.lyrics = lyrics
	
	def sing_me_a_song(self):
		for line in self.lyrics:
			print line

happy_bday = Song(["Happy birthday to you",
		   "I don't want to get sued",
		   "So I'll stop right there"])
				 
bulls_on_parade = Song(["They rally around the family" ,
			"With pockets full of shells"])

happy_bday.sing_me_a_song()

bulls_on_parade.sing_me_a_song()

输出结果如下:

c:\>python ex40.py
Happy birthday to you
I don't want to get sued
So I'll stop right there
They rally around the family
With pockets full of shells

研究训练:

1、写更多的歌词来做上述操作,确保你理解了你是传递了一个字符串列表作为 lyrics变量的值。
2、先把歌词放在了一个单独的变量中,然后把它传递给了类中的 lyrics 变量。
3、看看你能否破解它让它做更多的事情。如果你现在完全不知道怎么做也不用担心,尽管去尝试,看看会发生什么事情。分解它,修改它,再修改它,不要担心会伤到它。
4、在线搜索关于“面向对象编程”,试着让自己去充分理解这个概念。不要担心做完这些对你毫无作用。其中的一半知识对我来说也是毫无意义。

学生遇见的常见问题:

为什么当我在类中创建 __init__函数或者其他函数时需要加上 self 这个参数?
答:如果你不加上 self 话那么代码就像 cheese = 'Frank' 一样模糊不清。代码根本就不清楚cheese到底是一个实例的属性还是本地的一个名为cheese的变量。带有self.cheese = 'Frank'就非常清楚的告诉你self.cheese是一个类对象的实例属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值