37 题的其他符号有关的内容大多数之前都是学习过的,所以就不在发文来说了,而 38 读代码 更是一个需要自己线下完成的内容,因此也没必要单独拿出来写答案。
于是乎,一下子就来到了 39 题。
题目
本题的练习应该归类为复习和实践,在 32: 循环和列表 中我们了解了列表包含的方法,知道了 append
方法可以做到什么事情,Zed 建议我们复习之后进行本题的练习。
另外,他还为我们介绍了当执行 mystuff.append('hello')
时发生了什么:
- Python 看到你用到了
mystuff
,于是就去找到这个变量。也许它需要倒着检查看你有没有在哪里用 = 创建过这个变量,或者检查它是不是一个函数参数,或者看它是不是一个全局变量。不管哪种方式,它得先找到mystuff
这个变量才行。- 一旦它找到了
mystuff
,就轮到处理句点.
(period) 这个操作符,而且开始查看mystuff
内部的一些变量了。由于mystuff
是一个列表,Python 知道mystuff
支持一些函数。- 接下来轮到了处理
append
。Python 会将 “append” 和mystuff
支持的所有函数的名称一一对比,如果确实其中有一个叫 append 的函数,那么 Python 就会去使用这个函数。- 接下来 Python 看到了括号
(
(parenthesis) 并且意识到, “噢,原来这应该是一个函数”,到了这里,它就正常会调用这个函数了,不过这里的函数还要多一个参数才行。- 这个额外的参数其实是……
mystuff
! 我知道,很奇怪是不是?不过这就是Python 的工作原理,所以还是记住这一点,就当它是正常的好了。真正发生的事情其实是append(mystuff, 'hello')
,不过你看到的只是mystuff.append('hello')
。
对于这个过程的了解会有助于理解 python 的错误信息。虽然我们还没有学习“类”(class),不过我们知道了函数会有两个参数之后就不难理解下面这个错误信息
>>> class Thing(object):
... def test(hi):
... print(hi)
...
>>> a = Thing()
>>> a.test("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (2 given)
错误信息说 test()
只接受 1 个参数,然而实际上却传入了 2 个。也就证明 a.test("hello")
实际上正是被 python 翻译为 test(a, "hello")
才导致了错误的发生。
加分练习
- 将每一个被调用的函数以上述的方式翻译成 python 实际执行的动作。例如
' '.join(things)
其实是join(' ', things)
。 - 将这两种方式翻译为自然语言。例如
' ".join(things)
可以翻译成 “用 ’ ’ 连接(join) things”,而join(' ', things)
的意思是 “为 ’ ’ 和 things 调用 join 函数”。 - 在网上阅读一些关于 “面向对象编程 (Object Oriented Programming)” 的资料。不要怕看着晕,其实大家开始都晕,而《笨办法学 python》 会教给我们足够的知识逐步掌握它
- 了解 Python 的 class 是什么东西。一定是 Python 的哦
- 了解
dir(something)
和something
的 class 有什么关系? - Zed 建议,如果实在皋懂 面向对象编程(OOP)可以学习以下 “函数编程 (functional programming)”
我的答案
39.0 基础练习
ten_things = "Apples Oranges Crows Telephone Light Sugar"
print("Wait there's not 10 things in that list, let's fix that.")
# 字符串的 split 方法会把字符串按照参数隔开生成一个列表
stuff = ten_things.split(' ')
more_stuff = ["Day", "Night", "Song", "Frisbee", "Corn", "Banana", "Girl", "Boy"]
# 不断从 more_stuff 中取出元素加入 stuff 中直到
# stuff 的长度等于10,确认 while 循环会正确结束
while len(stuff) != 10:
next_one = more_stuff.pop()
print("Adding:", next_one)
stuff.append(next_one)
print("There's %d items now." % len(stuff))
print("There we go:", stuff)
print("Let's do some things with stuff.")
print(stuff[1])
print(stuff[-1])
print(stuff.pop())
print(' '.join(stuff))
print('#'.join(stuff[3:5]))
39.1 + 39.2 翻译函数语句
stuff = ten_things.split(' ')
翻译: ten_things
使用空格 分割为列表
实际执行 stuff = split(ten_things, ' ' )
翻译: 为 ten_things
和 调用
split
函数
next_one = more_stuff.pop()
翻译:more_stuff
使用 抛出方法
实际执行 pop(more_stuff)
翻译:调用 pop
函数,参数是 more_stuff
stuff.append(next_one)
翻译:为 stuff
末尾添加 next_one
实际执行 append(stuff, next_one)
翻译:为 stuff
和 next_one
调用 append
方法
stuff.pop()
翻译: 为 sutff
调用 pop
方法
实际执行 pop(suff)
翻译:调用 pop
函数,参数 suff
39.3 + 39.4 Python 面向对象编程
这里推荐两篇文章来理解和学习 python 的面向对象编程是怎么会是
《Python 面向对象(初级篇)》
武沛齐老师所著,这篇文章写作时间比较早一点使用的 python2 作为代码示例,但是非常的简洁清晰,唯一遗憾是对多态的介绍比较专业一些,新手不太容易理解到什么是 python 的多态。
Python3 教程 —— 面向对象编程
大家学习 python 肯定都知道廖雪峰老师吧,廖老师教程对于多态的介绍更详细一些
dir()
函数
dir(something)
会列出 something
所拥有的属性和函数。而当我们使用 class 创建一个类的时候,其中的属性和函数都可以通过 dir
列出来。