《零基础入门学习Python》第052讲:像极客一样去思考

本文讲述了Python的设计哲学,强调了Python标准库的重要性,以及如何有效地利用Python自带的文档来查找和学习模块。特别提到了timeit模块在性能测试中的作用,并展示了如何通过交互式解释器来了解和使用模块。此外,还介绍了PEP的作用和如何通过__doc__、__all__属性以及help()函数来学习新模块。
摘要由CSDN通过智能技术生成

0. 请写下这一节课你学习到的内容:格式不限,回忆并复述是加强记忆的好方式!

大家可能还不知道,在Python的社区里有句俗话:“Python自己带着电池(Batteries included)”,什么意思呢?要从Python的设计哲学说起,Python的设计哲学是:优雅、明确和简单。因此,Python开发者演变出来的哲学就是,用一种方法,最好是只有一种方法来做一件事。虽然我们常常努力大家多思考,条条大路通罗马,那是为了训练大家的发散式思维,但是在正式编程中,如果有完善、并且经过严密测试过的模块可以直接实现,那么我的建议是使用现成的模块来工作。

所以Python附带安装的有Python标准库,一般我们说的电池就是Python标准库中的模块,这些模块都极其有用,Python标准库中包含一般任务所需要的模块,不过呢,Python标准库包含的模块有100多个之多,一个个单独来讲那着实是不科学的,所以这一讲,我们将学习如何独立的来探索模块。

对于Python来说,学习资料其实一直都在身边(Python不仅带着电池,还带着充电器....),我们这里给大家分析,遇到问题,我们应该如何去找答案,其实90%的答案你都可以通过我们以下的方式来找到解决的方法。

首先要做的就是打开Python的文档,IDLE-Help-Python Docs(F1),如图:

What the huck!!! 都是鸟文啊,我看不懂怎么办,不会的话当然是学啊,说实话,对于一个程序员来说,还是需要一定的英语基础的,因为对于经济全球化的今天,最新最全的文档基本上都是鸟文的,所以你一点都不懂英语真的是很被动。不过大家也不要气馁,对于变成来说,只需要掌握基本的单词就行。

我们接着讲,那这个文档的基本部分包括哪些呢?

(1)What's new in Python3.5?

介绍了相比Python2.0来说的新的变动。

(2)Tutorial

简易的Python教程,简单介绍了Python的语法。

(3)Liberary Reference

Python的整编书,这里详细列举了Python所有内置函数和标准库的各个模块的用法,非常详细,但是,你从头到尾是看不完的,当做字典来查就可以了。

(4)Inatalling Python Modules

教你如何安装Python的第三方模块

(5)Distuributing Python Modules

教你如何发布Python的第三方模块,你需要知道,Python除了标准库的几百个官方模块之外,还有一个叫做 pypi 的社区,网站为:PyPI · The Python Package Index 搜集了全球Python爱好者贡献出来的模块,你自己也可以写一个模块发布到pypi社区,分享给全世界。

关于第三方模块,我将会在后面的笔记中为大家整理,

(6)language reference

讨论Python的语法和设计哲学

(7)Python setup and usage

谈论Python如何在不同平台上安装和使用

(8)Python HOWTOs

针对一些特定的主题进行深入并且详细的探讨

(9)Extending and Embedding

介绍如何用 C和 C++ 来开发Python的扩展模块,还有开发对应所需要的API

关于用 C和 C++ 为Python开发扩展,也会在后面的笔记中谈到。

(10)FAQs

常见问题解答

另外大家可能经常会看到的就是类似于这个 PEP 这个词语

PEP是Python Enhancement Proposals 的缩写,翻译过来就是Python增强建议书的意思。它是用来规范与定义Python的各种加强和延伸功能的技术规格,好让Python开发社区能有共同遵循的依据。

每一个PEP都有一个唯一的编号,这个编号一旦给定就不会再改变。例如,PEP 3000 就是用来定义 Python 3.0 的相关技术规格;而PEP 333 则是 Python 的 Web 应用程序界面 WSGI (Web Server Gateway Interface 1.0)的规范。关于PEP 本身的相关规范定义在 PEP 1,而PEP 8 则定义了 Python 代码的风格指南。

有关 PEP 的列表大家可以参考 PEP 0 :<PEP 0 – Index of Python Enhancement Proposals (PEPs) | peps.python.org>

接下来就来举个实例,说说我遇到问题是怎么自救的,前阵子,我们不是举了一个计时器的例子吗,后来在第44课的课后作业的最后面,我们说,现实编程中,计时器工具千万不要自己动手写,因为有很多未知的因素会影响到你的数据,所以我们建议使用现成的模块,这个模块叫做 timeit,来对你的代码来进行计时。假设我们现在不知道 timeit 模块的用法,我应该如何入手呢?

那我们就开始来翻刚才这个文档了,我们可以使用它的搜索、索引功能,一般给出的第一个都是你需要的

如果你认为快速学习一个模块都要读这么长一篇长篇大论,那你真是  too young too simple 了,快速掌握一个模块的用法,事实上可以使用IDLE 交互界面,首先 import 该模块,然后可以调用 __doc__属性,这样就可以查看到这个模块的简介,如图:

事实上你对于这个方法应该很熟悉了,这跟我们之间讲过的函数文档是一样的,就是写在模块最开头的那个字符串,这个字符串是带格式的,我们可以使用 print() 把这个格式打印出来。会更好看一点:

然后你可能需要知道这个模块里面定义了哪些变量,哪些函数,哪些类,你可以用 dir() 内置方法把它显示出来:

 
  1. >>> dir(timeit)

  2. ['Timer', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_globals', 'default_number', 'default_repeat', 'default_timer', 'dummy_src_name', 'gc', 'itertools', 'main', 'reindent', 'repeat', 'sys', 'template', 'time', 'timeit']

显示出来的这些并不是所有的名字对我们都有用,所以我们需要过滤一些我们不需要的东西,那你可能留意到 __all__这个属性了,这个属性其实就是帮助我们完成过滤的过程,我们调用 __all__属性:

 
  1. >>> timeit.__all__

  2. ['Timer', 'timeit', 'repeat', 'default_timer']

它返回给我们的依然是一个列表,但是相比上面的来说,只有其中的4个成员,如果你有看前面的关于 timeit 的文档的话,你会发现,Timer是一个类,timeit、repeat、default_timer 是3个接口函数。所以,我们这个 __all__ 属性显示出来的就是这个模块可以供外界调用的所有东西。

这里有两点需要注意的,首先,不是所有的模块都有 __all__ 属性,有 __all__ 的话,这个属性里面包含的内容就是作者希望外部调用的名字,其它的就是不希望外部调用的了。其次,第二点就是,如果一个模块设置了 __all__ 属性,那么使用 from ‘模块名’ import * 语句导入到命名空间的操作,只有 __all__ 属性这里面的名字才能被导入。例如:

 
  1. >>> from timeit import *

  2. >>> Timer

  3. <class 'timeit.Timer'>

  4. >>> gc

  5. Traceback (most recent call last):

  6. File "<pyshell#8>", line 1, in <module>

  7. gc

  8. NameError: name 'gc' is not defined

找 Timer 就可以找到,但是找 gc 就找不到。

但是如果你没有设置这个 __all__ 属性的话,from ‘模块名’ import * 就会把所有不以下划线开头的名字都导入到当前命名空间,所以,我们建议,你再编写模块的时候,对外提供接口函数和类都设置到 __all__ 属性的列表中去,这样子是比较规范的做法。

还有一个属性叫做 __file__ 属性,这个属性是指明了该模块的源代码所在的位置

 
  1. >>> import timeit

  2. >>> timeit.__file__

  3. 'D:\\ProgramFiles\\Anaconda3\\lib\\timeit.py'

我们说过,快速提高编程能力有三大法宝,一个就是不断地编写代码,第二个就是阅读高手的代码。

这里提供了源代码的路径,我们就可以去找到它,并通过阅读它的源代码,吸取它的精华。

最后我们还可以使用 help() 函数

在本节课的最后,我需要提一点的就是,timeit 这个模块真的是太有用了,所以呢,我这里有对应的文档的中文详解 -> timeit 模块详解。大家有空的话,建议通读一下。


测试题(笔试,不能上机哦~)

总共 16 道题,不上机的情况下答中 14 道以下请自觉忏悔!

注:题目虽然简单,但有陷阱,反正这一讲也没什么要测试的,就考考大家常识^_^

0. 请问以下代码会打印什么内容?

 
  1. >>> def func():

  2. pass

  3. >>> print(type(func()))

A. <type 'function'>
B. <type 'tuple'>
C. <type 'NoneType'>
D. <type 'type'>

答:C

1. 请问以下代码会打印什么内容?

>>> print(type(1J))

A. <type 'unicode'>
B. <type 'int'>
C. <type 'str'>
D. <type 'complex'>

答:D

2. 请问以下代码会打印什么内容?

>>> print(type(lambda:None))

A. <type 'NoneType'>
B. <type 'function'>
C. <type 'int'>
D. <type 'tuple'>

答:B

3. 请问以下代码会打印什么内容?

 
  1. >>> a = [1, 2, 3, "FishC", ('a', 'b', 'c'), [], None]

  2. >>> print(len(a))

A. 13
B. 7
C. 6
D. 5

答:B

4. 请问以下代码会打印什么内容?

 
  1. class A:

  2. def __init__(self, x):

  3. x = x + 1

  4. self.v1 = x

  5. class B(A):

  6. def __init__(self, x):

  7. x = x + 1

  8. self.v2 = x

  9. >>> b = B(8)

  10. >>> print("%d %d" % b.v1, b.v2)

A. 9 10
B. 9 9
C. 10 10
D. 抛出异常

答:D

5. 请问以下代码会打印什么内容?

 
  1. class A:

  2. def __init__(self, x):

  3. self.x = x

  4. x = 666

  5. >>> a = A()

  6. >>> a = A(888)

  7. >>> a.x

A. 666
B. 888
C. None
D. 抛出异常

答:B

6. 请问以下代码会打印什么内容?

 
  1. values = [1, 1, 2, 3, 5]

  2. nums = set(values)

  3. def checkit(num):

  4. if num in nums:

  5. return True

  6. else:

  7. return False

  8. for i in filter(checkit, values):

  9. print(i, end=' ')

A. 1 2 3 5
B. 1 1 2 3 5
C. 1 2 3 4 3 2 1
D. 抛出异常

答:B

7. 请问以下代码会打印什么内容?

 
  1. values = [1, 1, 2, 3, 5]

  2. def transform(num):

  3. return num ** 2

  4. for i in map(transform, values):

  5. print(i, end=' ')

A. 1 1 4 9 25
B. 1 1 2 3 5
C. 0.5 0.5 1 1.5 2.5
D. 2 2 4 6 10

答:A

8. 请问以下代码会打印什么内容?

 
  1. class A:

  2. def __init__(self, x):

  3. self.x = x

  4. a = A(100)

  5. a.__dict__['y'] = 50

  6. print(a.y + len(a.__dict__))

A. 2
B. 50
C. 51
D. 52

答:D

9. 请问以下代码会打印什么内容?

 
  1. class A:

  2. def __init__(self):

  3. pass

  4. def get(self):

  5. print(__name__)

  6. >>> a = A()

  7. >>> a.get()

A. A
B. a
C. __main__
D. _A__a

答:C

10. 请问以下代码会打印什么内容?

 
  1. country_counter = {}

  2. def addone(country):

  3. if country in country_counter:

  4. country_counter[country] += 1

  5. else:

  6. country_counter[country] = 1

  7. addone('China')

  8. addone('Japan')

  9. addone('China')

  10. addone("American")

  11. print(len(country_counter))

A. 0
B. 1
C. 2
D. 3

答:D

11.请问以下代码会打印什么内容?

 
  1. dict1 = {}

  2. dict1[1] = 1

  3. dict1['1'] = 2

  4. dict1[1.0] = 3

  5. result = 0

  6. for each in dict1:

  7. result += dict1[each]

  8. print(result)

A. 2
B. 3
C. 5
D. 6

答:C

12. 请问以下代码会打印什么内容?

 
  1. def dostuff(param1, *param2):

  2. print type(param2)

  3. dostuff('apples', 'bananas', 'cherry', 'dates')

A. <type 'int'>
B. <type 'str'>
C. <type 'tuple'>
D. <type 'dict'>

答:C

13. 请问以下代码会打印什么内容?

 
  1. class A:

  2. def __init__(self, a, b, c):

  3. self.x = a + b + c

  4. a = A(1,2,3)

  5. b = getattr(a, 'x')

  6. setattr(a, 'x', b+1)

  7. print a.x

A. 1
B. 2
C. 6
D. 7

答:D

14. 请问以下代码会打印什么内容?

 
  1. list1 = [1, 2]

  2. list2 = [3, 4]

  3. dict1 = {'1':list1, '2':list2}

  4. dict2 = dict1.copy()

  5. dict1['1'][0] = 5

  6. result = dict1['1'][0] + dict2['1'][0]

  7. print(result)

A. 5
B. 6
C. 8
D. 10

答:D

15. 请问以下代码会打印什么内容?

 
  1. import copy

  2. list1 = [1, 2]

  3. list2 = [3, 4]

  4. dict1 = {'1':list1, '2':list2}

  5. dict2 = copy.deepcopy(dict1)

  6. dict1['1'][0] = 5

  7. result = dict1['1'][0] + dict2['1'][0]

  8. print(result)

A. 5
B. 6
C. 8
D. 10

答:B

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值