- 译者序
- 前言
- 第1章 问答环节
- 第2章 Python 如何运行程序
- 第3章 如何运行程序
- 第4章 介绍 Python 对象类型
- 第5章 数字
- 第6章 动态类型简介
- 第7章 字符串
- 第8章 列表与字典
- 第9章 元组、文件及其他
- 第10章 Python 语句简介
- 第11章 赋值、表达式和打印
- 第12章 if 测试和语法规则
- 第13章 while 和 for 循环
- 第14章 迭代器和解析,第一部分
- 第15章 文档
- 第16章 函数基础
- 第17章 作用域
- 第18章 参数
- 第19章 函数的高级话题
- 第20章 迭代和解析,第二部分
- 第21章 模块:宏伟蓝图
- 第22章 模块代码编写基础
- 第23章 模块包
- 第24章 高级模块话题
- 第25章 OOP:宏伟蓝图
- 第27章 更多实例
- 第28章 类代码编写细节
- 第29章 运算符重载
- 第30章 类的设计
- 第31章 类的高级主题
- 第32章 异常基础
- 第34章 异常对象
- 第35章 异常的设计
- 第36章 Unicode 和字节字符串
- 字符串基础知识
- Python 的字符串类型
- 文本和二进制文件
- Python 3.0 中的字符串应用
- 转换
- 编码 Unicode 字符串
- 编码非ASCII文本
- 编码和解码非ASCII文本
- 其他 Unicode 编码技术
- 转换编码
- 在 Python 2.6 中编码 Unicode 字符串
- 源文件字符集编码声明
- 使用 Python 3.0 Bytes 对象
- 序列操作
- 创建 bytes 对象的其他方式
- 混合字符串类型
- 使用 Python 3.0(和 Python 2.6)bytearray 对象
- 使用文本文件和二进制文件
- Python 3.0 中的文本和二进制模式
- 类型和内容错误匹配
- 使用 Unicode 文件
- 在 Python 3.0 中处理 BOM
- Python 2.6 中的 Unicode 文件
- Python 3.0 中其他字符串工具的变化
- Struct二进制数据模块
- pickle对象序列化模块
- XML解析工具
- 本章小结
- 本章习题
- 习题解答
- 第37章 管理属性
- 第38章 装饰器
- 第39章 元类
- 附录A 安装和配置
- 附录B 各部分练习题的解答
- 作者介绍
- 封面介绍
第五部分 模块
1.导入基础。这一道题比你想象的更简单。做完后,文件(mymod.py)和交互的结果看起来如下所示。记住,Python可以把整个文件读成字符串列表,而len内置函数可返回字符串和列表的长度:
这些函数一次把整个文件加载到了内存中,当文件过大以至于机器的内存无法容纳时,就不能用了。为了更健壮一些,你可以改用迭代器逐行读取,在此过程中进行计数:
在UNIX上,你可以使用wc命令确认输出。在Windows中,对文件单击鼠标右键,来查看其属性。但是请注意,你的脚本报告的字符数可能会比Windows的少:为了可移植,Python把Windows\r\n行尾标识符转换成了\n,每行会少一个字节(字符)。为了和Windows的字节计数相同,你得使用二进制模式打开文件('rb'),或者根据行数,加上对应的字节数。
顺便提一下,要做这道练习题中的“志向远大”的部分(传入文件对象,只打开文件一次),你可能需要使用内置文件对象的seek方法。本书没有提到,但其工作起来就像C的fseek调用(也是调用seek):seek会把文件当前位置重设为传入的偏移值。seek运行后,未来的输入/输出运算就是相对于新位置而开始的。想要回滚到文件开头位置而又不关闭文件并重新打开,就需要调用file.seek(0)。文件的read方法会从文件当前位置开始读起,你得回滚到开头重新读取文件。下面是调整后的程序:
2.from/from*。这里是from*部分;把*换成countChars就是其余的答案:
3.__main__。如果你写得正确的话,哪种模式都能使用(运行程序或模块导入):
在这里可能应该开始考虑使用命令行参数或用户输入来提供要统计的文件名,而不是在脚本中硬编码它(参见第24章了解关于sys.argv的更多内容,参见第10章了解关于输入的更多内容):
4.嵌套导入。下面是该题的解答(myclient.py文件):
至于这个问题的其余部分,因为from只是在导入者中赋值变量名,所以mymod的函数可以在myclient的顶层存取(可导入),就好像mymod的def是位于myclient中。例如,另一个文件可以写成:
如果myclient用的是import而不是from,就需要使用路径,通过myclient以获得mymod中的函数:
通常来说,你可以定义收集器模块,从其他模块导入所有的变量名,使得那些变量名能在单个方便的模块中使用。使用下面的代码,最后会有变量名somename的三个不同拷贝(mod1.somename、collector.somename以及__main__.somename)。这三个名称都共享相同的整数对象,而只有在交互模式提示符下存在着变量名somename:
5.导入包。在这个练习题中,把练习题3的解答mymod.py文件放到一个目录包中。下面是我们所做的事:在Windows命令提示字符界面下,创建目录以及所需要的__init__.py文件。如果是其他的平台,你得进行修改(例如,使用mv和vi,而不是move和edit)。这些命令对于任意目录都适用(只是刚好在Python安装目录下运行命令),而你也可以从文件管理器GUI界面下完成其中的一些事。
当这样做以后,就有个mypkg子目录含有文件__init__.py和mymod.py。mypkg目录内需要有__init__.py,但其上层目录则不需要。mypkg位于模块搜索路径的主目录上。目录的初始设置文件中所写的print语句只会在导入时执行一次,不会有第二次:
6.重载。这道题只是要你实验一下修改本书的changer.py这个例子,所以这里没什么好写的。
7.循环导入。简单来说,结果就是先导入recur2,因为递归导入是发生在recur1中的import,而不是recur2的from。
详细来讲是这样的:先导入recur2,这是因为从recur1到recur2的递归导入是整个取出recur2,而不是获取特定的变量名。从recur1导入时,recur2还不完整,因为其使用import而不是from,所以安全。Python会寻找并返回已创建的recur2模块对象,然后继续运行recur1剩余的部分,从而没有问题。当recur2的导入继续下去时,第二个from发现recur1(已完全执行)内的变量名Y,所以不会报告错误。把文件当成脚本执行与将其当成模块导入并不相同。这些情况与通过交互模式先运行脚本中的第一个import或from相同。例如,将recur1作为脚本执行,与通过交互模式导入recur2一样,因为recur2是recur1中导入的第一个模块。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论