笨办法学 Python3 第五版(预览)(二)(3)

简介: 笨办法学 Python3 第五版(预览)(二)(3)

笨办法学 Python3 第五版(预览)(二)(2)https://developer.aliyun.com/article/1483431

通过以下方式创建数据对象:

  1. {(大括号)打开它
  2. 写入键,这里是一个字符串,但可以是数字,或几乎任何东西
  3. 写入一个:(冒号)
  4. 写入值,可以是 Python 中有效的任何内容

一旦你这样做,你可以像这样访问这封 Python 电子邮件:

1   email["From"]
2   'j.smith@example.com'
3
4   email["To"]
5   'zed.shaw@example.com'
6
7   email["Subject"]
8   'I HAVE AN AMAZING INVESTMENT FOR YOU!!!'

你会注意到这与你访问模块中的变量和函数的方式非常相似,你需要require。使用.(点)是你可以访问 Python 中许多数据结构部分的主要方式。你也可以使用前一个练习中的[]语法来访问这些数据:

1   email['To']
2   'zed.shaw@example.com'
3
4   email['From']
5   'j.smith@example.com'

list索引的唯一区别是你使用字符串(‘From’)而不是整数。但是,如果你愿意,你也可以使用整数作为键(后面会详细介绍)。

将列表与数据对象结合

编程中的一个常见主题是将组件组合以获得令人惊讶的结果。有时惊喜是崩溃或错误。其他时候,惊喜是一种新颖的完成某项任务的方式。无论如何,当你进行新颖的组合时发生了什么并不是真正的惊喜或秘密。对于来说可能是惊喜的,但语言规范中通常会有一个解释(即使这个原因绝对愚蠢)。你的计算机中没有魔法,只有你不理解的复杂性。

将数据对象放入lists中的一个很好的例子。你可以这样做:

1   messages = [
2     {to: 'Sun', from: 'Moon', message: 'Hi!'},
3     {to: 'Moon', from: 'Sun', message: 'What do you want Sun?'},
4     {to: 'Sun', from: 'Moon', message: "I'm awake!"},
5     {to: 'Moon', from: 'Sun', message: 'I can see that Sun.'}
6   ];

一旦我这样做了,我现在可以使用list语法来访问数据对象,就像这样:

1   messages[0].to
 2   'Sun'
 3
 4   messages[0].from
 5   'Moon'
 6   messages[0].message
 7   'Hi!'
 8
 9   messages[1]['to']
10   'Moon'
11
12   messages[1]['from']
13   'Sun'
14
15   messages[1]['message']
16   'What do you want Sun?'

注意我在messages[0]后面立即使用.(点)语法的方式?再次尝试结合功能,看看它们是否有效,如果有效,找出原因,因为总会有一个原因(即使它很愚蠢)。

代码

现在,你将重复使用lists的练习,并写出我精心制作的三个数据对象。然后,你将把它们输入到 Python 中,并尝试访问我给你的数据。记得尝试在脑海中完成这个任务,然后用 Python 检查你的工作。你还应该练习对listdict结构进行这样的操作,直到你有信心可以访问内容。你会意识到数据是相同的,只是被重新构造了。

列表 24.1: ex24.py

1   fruit = [
 2       {kind: 'Apples',  count: 12, rating: 'AAA'},
 3       {kind: 'Oranges', count: 1,  rating: 'B'},
 4       {kind: 'Pears',   count: 2,  rating: 'A'},
 5       {kind: 'Grapes',  count: 14, rating: 'UR'}
 6   ];
 7
 8   cars = [
 9       {type: 'Cadillac', color: 'Black', size: 'Big', miles: 34500},
10       {type: 'Corvette', color: 'Red', size: 'Little', miles: 1000000},
11       {type: 'Ford', color: 'Blue', size: 'Medium', miles: 1234},
12       {type: 'BMW', color: 'White', size: 'Baby', miles: 7890}
13   ];
14
15   languages = [
16       {name: 'Python', speed: 'Slow', opinion: ['Terrible', 'Mush']},
17       {name: 'JavaScript', speed: 'Moderate', opinion: ['Alright', 'Bizarre'
         ↪] ]},
18       {name: 'Perl6', speed: 'Moderate', opinion: ['Fun', 'Weird']},
19       {name: 'C', speed: 'Fast', opinion: ['Annoying', 'Dangerous']},
20       {name: 'Forth', speed: 'Fast', opinion: ['Fun', 'Difficult']},
21   ];

你应该看到的结果

请记住,你在这里进行了一些复杂的数据访问操作,所以要慢慢来。你必须遍历你分配给模块的data变量,然后访问lists,接着是数据对象,有时还有另一个list

挑战

我会给你完全相同的数据元素集,你需要找出获取这些信息所需的索引。例如,如果我告诉你fruit 'AAA',那么你的答案是fruit[0].rating。你应该试着在脑海中通过查看代码来做到这一点,然后在python shell 中测试你的猜测。

水果挑战

你需要从fruit变量中取出所有这些元素:

  • 12
  • ‘AAA’
  • 2
  • ‘橙子’
  • ‘葡萄’
  • 14
  • ‘苹果’
汽车挑战

你需要从cars变量中取出所有这些元素:

  • ‘大的’
  • ‘红色的’
  • 1234
  • ‘白色的’
  • 7890
  • ‘黑色的’
  • 34500
  • ‘蓝色的’
语言挑战

你需要从languages变量中取出所有这些元素:

  • ‘慢的’
  • ‘好的’
  • ‘危险的’
  • ‘快的’
  • ‘困难的’
  • ‘有趣的’
  • ‘烦人的’
  • ‘奇怪的’
  • ‘适度的’

最终挑战

你的最终挑战是编写出写出与练习 23 中相同歌词的 Python 代码。再次慢慢来,试着在脑海中完成再看看你是否做对了。如果你做错了,花时间理解为什么错了。作为对比,我在脑海中一次性写出了歌词,没有出错。我也比你有更多经验,所以你可能会犯一些错误,那也没关系。

你不知道这些是歌词吗?这是一首由王子演唱的歌曲叫做“Little Red Corvette”。在继续阅读本书之前,你现在被命令听 10 首王子的歌曲,否则我们就不能再做朋友了。再也不能!

练习 25:字典和函数

在这个练习中,我们将通过将函数与dict结合起来做一些有趣的事情。这个练习的目的是确认你可以在 Python 中组合不同的东西。组合是编程的关键方面,你会发现许多“复杂”的概念实际上只是更简单概念的组合。

第一步:函数名称是变量

为了做好准备,我们首先要确认函数的名称就像其他变量一样。看看这段代码:

1   def print_number(x):
2       print("NUMBER IS", x)
3
4   rename_print = print_number
5   rename_print(100)
6   print_number(100)

如果你运行这段代码,你会发现rename_printprint_number做的事情完全相同,这是因为它们是相同的。函数的名称与变量的名称相同,你可以将名称重新分配给另一个变量。这就像这样做一样:

1   x = 10
2   y = x

玩弄这个,直到你明白。创建自己的函数,然后将它们分配给新名称,直到你理解这个概念。

第二步:带有变量的字典

这可能很明显,但以防你还没有建立联系,你可以将一个变量放入dict中:

1   color = "Red"
2
3   corvette = {
4   "color": color
5   }
6
7   print("LITTLE", corvette["color"], "CORVETTE")

接下来的拼图部分是有意义的,因为你可以将数字和字符串等值放入dict中。你也可以将这些相同的值分配给变量,因此将它们组合起来并将变量放入dict中是有意义的。

第三步:带有函数的字典

你应该看到这是怎么回事了,但现在我们可以将这些概念结合起来,将一个函数放入dict中:

1   def run():
 2    print("VROOM")
 3
 4   corvette = {
 5     "color": "Red",
 6     "run": run
 7   }
 8
 9   print("My", corvette["color"], "can go")
10   corvette["run"]()

我从前面的color变量中取出,并将其直接放入corvettedict中。然后我创建了一个名为run的函数,并将其放入corvette中。最棘手的部分是最后一行corvette ["run"](),但看看你是否可以根据你所知道的来弄清楚它。在继续之前,花些时间写出这行代码正在做什么的描述。

第四步:解密最后一行

解密最后一行corvette["run"]()的技巧是将其分解成每个部分。人们对这样的代码行感到困惑的原因是他们看到了一个单一的东西,“运行 corvette”。事实上,这行代码由许多东西组合在一起共同工作。如果我们将其拆分开来,我们可以得到这段代码:

1   # get the run fuction out of the corvette dict
2   myrun = corvette["run"]
3   # run it
4   myrun()

即使这两行并不是整个故事,但这向你展示了这至少是一行上的两个操作:使用["run"]获取函数,然后使用()运行函数。为了进一步分解这个,我们可以写成:

  1. corvette告诉 Python 加载dict
  2. [告诉 Python 开始索引到corvette
  3. "run"告诉 Python 使用"run"作为键来搜索dict
  4. ]告诉 Python 你已经完成索引,它应该完成索引
  5. Python 然后返回与键"run"匹配的corvette内容,这是之前的run()函数
  6. Python 现在有了run函数,所以()告诉 Python 像调用任何其他函数一样调用它

花些时间理解这是如何工作的,并在corvette上编写自己的函数以使其执行更多操作。

学习练习

现在你有一段控制汽车的好代码。在这个练习中,你将创建一个新的函数,创建任何汽车。你的创建函数应满足以下要求:

  1. 它应接受参数来设置颜色、速度或其他你的汽车可以做的任何事情。
  2. 它应创建一个包含正确设置并已包含你创建的所有函数的dict
  3. 它应返回这个dict,这样人们可以将结果分配给任何他们想要的东西,并以后使用。
  4. 它应该被编写成这样,以便某人可以创建任意数量的不同汽车,每个他们制造的汽车都是独立的。
  5. 你的代码应通过改变几辆不同汽车的设置来测试#4,然后确认它们没有改变其他汽车的设置。

这个挑战不同,因为我会在后面的练习中向你展示挑战的答案。如果你在这个挑战中遇到困难,那么暂时搁置它,继续前进。你很快会再次看到它。

练习 26:字典和模块

在这个练习中,你将探索dict如何与模块一起工作。每当你使用import将“功能”添加到你自己的 Python 源代码时,你都在使用模块。你在练习 17 中使用得最多,所以在开始这个练习之前,最好回顾一下那个练习。

步骤 1: import的回顾

第一步是回顾import的工作方式并进一步发展这方面的知识。花点时间将这段代码输入到一个名为ex26.py的 Python 文件中。你可以在 Jupyter 中通过创建一个文件(左侧,蓝色[+]按钮)来做到这一点:

列表 26.1: ex26.py

1   name = "Zed"
2   height = 74

创建了这个文件后,你可以用这个导入它:

列表 26.2: ex26_code.py

1   import ex26

这将把ex26.py的内容带入你的 Jupyter lab 中,这样你就可以像这样访问它们:

列表 26.3: ex26_code.py

1   print("name", ex26.name)
2   print("height", ex26.height)

尽可能多地尝试玩这个。尝试添加新变量并再次导入以查看其工作原理。

步骤 2: 找到__dict__

一旦你理解了import是将ex26.py的内容导入到你的 lab 中,你就可以开始像这样调查__dict__变量:

列表 26.4: ex26_code.py

1   from pprint import pprint
2
3   pprint(ex26.__dict__)

pprint函数是一个“漂亮打印机”,将以更好的格式打印__dict__

使用pprint,你会突然发现ex26有一个名为__dict__的“隐藏”变量,它实际上是一个包含模块中所有内容的dict。你会在 Python 中的各个地方找到这个__dict__和许多其他秘密变量。__dict__的内容包含了许多不是你的代码的东西,但这只是 Python 需要处理模块的东西。

这些变量是如此隐藏,以至于即使顶级专业人员也会忘记它们的存在。许多这样的程序员认为模块与dict完全不同,而实际上模块使用了__dict__,这意味着它dict相同。唯一的区别是 Python 有一些语法,让你使用.运算符而不是dict语法来访问模块,但你仍然可以像访问dict一样访问内容:

列表 26.5: ex26_code.py

1   print("height is", ex26.height)
2   print("height is also", ex26\. dict ['height'])

对于这两种语法,你会得到相同的输出,但.模块语法肯定更容易。

步骤 3: 改变__dict__

如果一个模块确实是内部的dict,那么这意味着改变__dict__的内容也应该改变模块中的变量。让我们试一试:

列表 26.6: ex26_code.py

1   print(f"I am currently {ex26.height} inches tall.")
2
3   ex26\. dict ['height'] = 1000
4   print(f"I am now {ex26.height} inches tall.")
5
6   ex26.height = 12
7   print(f"Oops, now I'm {ex26\. dict ['height']} inches tall.")

正如你所看到的,当你改变ex26.__dict__['height']时,变量ex26.height也会改变,这证明了模块确实是__dict__

这意味着.运算符被转换为__dict__[]访问操作。我希望你记住这一点,因为很多初学者看到ex26.height时,他们认为这是一个单独的代码单元。实际上,这实际上是三个或四个单独的操作:

  1. 找到ex26
  2. 找到ex26.__dict__
  3. 使用"height"索引到__dict__
  4. 返回该值。

一旦你建立了这种联系,你就会开始理解.是如何工作的。

学习练习:找到“Dunders”

__dict__ 变量通常被称为“双下划线”变量,但程序员们很懒,所以我们只是称它们为“dunder 变量”。在学习关于 dunder 变量的最后一步中,你将访问 Python 文档中描述数据模型的部分,其中描述了许多这些 dunder 的用法。

这是一个很大的文档,其写作风格非常枯燥,所以最好的学习方法是搜索__(双下划线),然后根据其描述找到访问这个变量的方法。例如,你可以尝试在几乎任何地方访问__doc__

列表 26.7: ex26_code.py

1   from pprint import pprint
2   print(pprint. doc )

这将为你提供与pprint函数相关联的一点文档。你可以使用help函数访问相同的信息:

列表 26.8: ex26_code.py

1   help(pprint)

尝试用你能找到的所有其他 dunder 进行这些实验。你很可能不会直接使用它们,但了解 Python 内部工作原理是很有好处的。

练习 27:编程游戏的五个简单规则

信息

这个练习旨在在你学习下一个练习时定期学习。你应该慢慢来,将其与其他解释混合在一起,直到最终理解。如果在这个练习中迷失了方向,休息一下,然后进行下一个练习。然后,如果在后面的练习中感到困惑,回来学习我在这里描述的细节。一直坚持下去,直到“豁然开朗”。记住,你不会失败,所以继续努力直到理解为止。

如果你玩围棋或国际象棋这样的游戏,你会知道规则相当简单,但它们所启用的游戏却极其复杂。真正好的游戏具有简单规则和复杂互动的独特品质。编程也是一个具有少量简单规则的游戏,这些规则创造了复杂的互动,在这个练习中,我们将学习这些规则是什么。

在我们做这个之前,我需要强调的是,当你编写代码时,你很可能不会直接使用这些规则。有些语言确实直接利用这些规则,你的 CPU 也使用它们,但在日常编程中你很少会使用它们。如果是这样,那么为什么要学习这些规则呢?

因为这些规则无处不在,理解它们将帮助你理解你编写的代码。当代码出错时,它将帮助你调试代码。如果你想知道代码是如何工作的,你将能够将其“分解”到基本规则,真正看到它是如何工作的。这些规则就像是一个秘密的代码。完全是故意的双关语。

我还要警告你不要期望立即完全理解这一点。把这个练习看作是为本模块中其余练习做准备。你应该深入研究这个练习,当遇到困难时,继续进行下一个练习作为休息。你应该在这个练习和下一个练习之间来回跳动,直到概念“豁然开朗”并开始变得有意义。你也应该尽可能深入地研究这些规则,但不要在这里卡住。挣扎几天,继续前进,回来,继续努力。只要你继续努力,你实际上不可能“失败”。

规则 1:一切都是一系列指令

所有程序都是一系列指令,告诉计算机做某事。当你输入这样的代码时,你已经看到 Python 在做这个了:

1   x = 10
2   y = 20
3   z = x + y

这段代码从第 1 行开始,到第 2 行,依此类推直到结束。这是一系列指令,但在 Python 中,这三行被转换为另一系列指令,看起来像这样:

1   LOAD_CONST  0 (10) # load the number 10
 2   STORE_NAME  0 (x)  # store that in x
 3
 4   LOAD_CONST  1 (20) # load the number 20
 5   STORE_NAME  1 (y)  # store that in y
 6
 7   LOAD_NAME   0 (x)  # loads x (which is 10)
 8   LOAD_NAME   1 (y)  # loads y (which is 20)
 9   BINARY_ADD         # adds those
10   STORE_NAME  2 (z)  # store the result in z

这看起来与 Python 版本完全不同,但我敢打赌你可能能够猜出这一系列指令在做什么。我已经添加了注释来解释每个指令,你应该能够将其与之前的 Python 代码联系起来。

我不是在开玩笑。现在花点时间将 Python 代码的每一行与这个“字节码”的行联系起来。使用我提供的注释,我相信你可以弄清楚,这样做可能会在你的脑海中点亮一盏灯,让你更好地理解 Python 代码。

不需要记住这些指令,甚至不需要理解每一条指令。你应该意识到的是,你的 Python 代码被翻译成了一系列简单的指令,告诉计算机做什么。这个指令序列被称为“字节码”,因为它通常以一系列计算机理解的数字的形式存储在文件中。你在上面看到的输出通常被称为“汇编语言”,因为它是这些字节的人类“可读”(勉强)版本。

这些简单的指令从顶部开始处理,一次执行一个小操作,当程序退出时到达末尾。这就像你的 Python 代码,但语法更简单,是INSTRUCTION OPTIONS的形式。另一种看待这个问题的方式是,x = 10的每个部分可能会在这个“字节码”中成为自己的指令。

这是《编码游戏》的第一条规则:你写的每一行最终都会成为一系列字节,作为计算机的指令输入,告诉计算机应该做什么。

我怎样才能得到这个输出?

要自己得到这个输出,你可以使用一个名为[dis](https://docs.python.org/3/library/dis.xhtml)的模块,它代表“disassemble”。这种代码传统上被称为“字节码”或“汇编语言”,所以dis的意思是“反汇编”。要使用dis,你可以导入它并像这样使用dis()函数:

1   # import the dis function
2   from dis import dis
3
4   # pass code to dis() as a string
5   dis('''
6   x = 10
7   y = 20
8   z = x + y
9   ''')

笨办法学 Python3 第五版(预览)(二)(4)https://developer.aliyun.com/article/1483437

相关文章
|
9天前
|
数据可视化 定位技术 Python
笨办法学 Python3 第五版(预览)(三)(3)
笨办法学 Python3 第五版(预览)(三)(3)
26 1
|
9天前
|
存储 Shell Ruby
笨办法学 Python3 第五版(预览)(三)(2)
笨办法学 Python3 第五版(预览)(三)(2)
26 0
|
9天前
|
存储 程序员 索引
笨办法学 Python3 第五版(预览)(二)(4)
笨办法学 Python3 第五版(预览)(二)(4)
40 1
|
9天前
|
程序员 Python
笨办法学 Python3 第五版(预览)(一)(2)
笨办法学 Python3 第五版(预览)(一)(2)
41 1
|
9天前
|
程序员 iOS开发 MacOS
笨办法学 Python3 第五版(预览)(一)(1)
笨办法学 Python3 第五版(预览)(一)(1)
67 1
|
6月前
|
Web App开发 前端开发 JavaScript
Python Selenium 浏览器打印预览
Python Selenium 浏览器打印预览
|
Rust 网络协议 IDE
Python语言学习路线及技术汇总预览
Rust语言是一种新型的系统编程语
84 0
Python语言学习路线及技术汇总预览
|
机器学习/深度学习 SQL 前端开发
Python语言学习路线及技术汇总预览
Python语言学习路线及技术汇总预览
123 0
Python语言学习路线及技术汇总预览
|
2天前
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
19 1