Python核心技术与实战
景霄
Facebook资深工程师
立即订阅
13891 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 从工程的角度深入理解Python
免费
基础篇 (14讲)
01 | 如何逐步突破,成为Python高手?
02 | Jupyter Notebook为什么是现代Python的必学技术?
03 | 列表和元组,到底用哪一个?
04 | 字典、集合,你真的了解吗?
05 | 深入浅出字符串
06 | Python “黑箱”:输入与输出
07 | 修炼基本功:条件与循环
08 | 异常处理:如何提高程序的稳定性?
09 | 不可或缺的自定义函数
10 | 简约不简单的匿名函数
11 | 面向对象(上):从生活中的类比说起
12 | 面向对象(下):如何实现一个搜索引擎?
13 | 搭建积木:Python 模块化
14 | 答疑(一):列表和元组的内部实现是怎样的?
进阶篇 (11讲)
15 | Python对象的比较、拷贝
16 | 值传递,引用传递or其他,Python里参数是如何传递的?
17 | 强大的装饰器
18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?
19 | 深入理解迭代器和生成器
20 | 揭秘 Python 协程
21 | Python并发编程之Futures
22 | 并发编程之Asyncio
23 | 你真的懂Python GIL(全局解释器锁)吗?
24 | 带你解析 Python 垃圾回收机制
25 | 答疑(二):GIL与多线程是什么关系呢?
规范篇 (7讲)
26 | 活都来不及干了,还有空注意代码风格?!
27 | 学会合理分解代码,提高代码可读性
28 | 如何合理利用assert?
29 | 巧用上下文管理器和With语句精简代码
30 | 真的有必要写单元测试吗?
31 | pdb & cProfile:调试和性能分析的法宝
32 | 答疑(三):如何选择合适的异常处理方式?
量化交易实战篇 (8讲)
33 | 带你初探量化世界
免费
34 | RESTful & Socket: 搭建交易执行层核心
35 | RESTful & Socket: 行情数据对接和抓取
36 | Pandas & Numpy: 策略与回测系统
免费
37 | Kafka & ZMQ:自动化交易流水线
38 | MySQL:日志和数据存储系统
39 | Django:搭建监控平台
40 | 总结:Python中的数据结构与算法全景
技术见闻与分享 (4讲)
41 | 硅谷一线互联网公司的工作体验
42 | 细数技术研发的注意事项
加餐 | 带你上手SWIG:一份清晰好用的SWIG编程实践指南
43 | Q&A:聊一聊职业发展和选择
结束语 (1讲)
结束语 | 技术之外的几点成长建议
Python核心技术与实战
登录|注册

13 | 搭建积木:Python 模块化

景霄 2019-06-07
你好,我是景霄。
这是基础版块的最后一节。到目前为止,你已经掌握了 Python 这一门当代武功的基本招式和套路,走出了新手村,看到了更远的世界,有了和这个世界过过招的冲动。
于是,你可能开始尝试写一些不那么简单的系统性工程,或者代码量较大的应用程序。这时候,简单的一个 py 文件已经过于臃肿,无法承担一个重量级软件开发的重任。
今天这节课的主要目的,就是化繁为简,将功能模块化、文件化,从而可以像搭积木一样,将不同的功能,组件在大型工程中搭建起来。

简单模块化

说到最简单的模块化方式,你可以把函数、类、常量拆分到不同的文件,把它们放在同一个文件夹,然后使用 from your_file import function_name, class_name 的方式调用。之后,这些函数和类就可以在文件内直接使用了。
# utils.py
def get_sum(a, b):
return a + b
# class_utils.py
class Encoder(object):
def encode(self, s):
return s[::-1]
class Decoder(object):
def decode(self, s):
return ''.join(reversed(list(s)))
# main.py
from utils import get_sum
from class_utils import *
print(get_sum(1, 2))
encoder = Encoder()
decoder = Decoder()
print(encoder.encode('abcde'))
print(decoder.decode('edcba'))
########## 输出 ##########
3
edcba
abcde
我们来看这种方式的代码:get_sum() 函数定义在 utils.py,Encoder 和 Decoder 类则在 class_utils.py,我们在 main 函数直接调用 from import ,就可以将我们需要的东西 import 过来。
非常简单。
但是这就足够了吗?当然不,慢慢地,你会发现,所有文件都堆在一个文件夹下也并不是办法。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Python核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(60)

  • Jingxiao 置顶
    思考题答案:
    很多回复说的很对,from module_name import * 会把 module 中所有的函数和类全拿过来,如果和其他函数名类名有冲突就会出问题;import model_name 也会导入所有函数和类,但是调用的时候必须使用 model_name.func 的方法来调用,等于增加了一层 layer,有效避免冲突。
    2019-06-09
    1
    53
  • jim
    from module_name import * 是导入module_name 内的所有内容,可以直接调用内部方法;import module_name,则是导入module_name,在代码中必须写成module_name.function的形式。
    2019-06-07
    17
  • 书了个一
    老师端午节快乐!
    2019-06-07
    7
  • helloworld
    本文中说在 Python 3 规范中,包目录下的__init__.py 并不是必须的,这个我想补充一下,这个__init__.py最好还是有,并且在这个文件里面通过from . import module的形式把该目录下的所有模块文件都写上,如果不这样做,我们只能通过from 包目录 import 模块 的方式来正确使用,而如果直接 import 包目录 的话,虽然import过程不会报错,但是我们在使用该包目录下的模块的时候就会报找不到模块的错误了!
    2019-07-16
    6
  • Kuzaman
    找到一种通用的加载环境变量的方法,很适用于 python虚拟环境virtualenvwrapper-win:
    原理:python运行时都会先去site-packages目录下寻找.pth文件,如果有就先加载里面的路径到环境变量中。
    操作:在X:\Python36\Lib\site-packages目录下增加一个 xxx.pth文件文件内容是要运行项目的绝对地址,windows操作系统记得使用 \\ 作为分隔符。
    如果项目路径中有中文,运行python会报错:“UnicodeDecodeError: 'gbk' codec can't decode byte 0xaa in position 42: illegal multibyte sequence”。
    解决方案:修改python环境源码 X:\Python36\lib\site.py的159行,由【f = open(fullname, "r")】修改为【f = open(fullname, "r",encoding='utf-8')】
    2019-06-21
    4
  • Smirk
    这节不错,目录结构那个之前一直用相对路径,但是觉得不干净,也奇怪为什么pycharm可以,但没深究,终于等到老师的文字,赞
    2019-06-14
    3
  • enjoylearning
    作者写的都是原来疑惑的地方,如有时候要新建一个模块总是纠结于是添加文件夹还是包,怀疑加文件夹是不是不如加包规范,有时面对每个文件夹一个空的__init__.py,觉得真是不够优雅,现在好了,原来是2和3的区别,以后可以大胆的用文件夹来组织模块了。另外就是觉得python 命名模块名不能像java和.net那样以公司名.application.web.api格式,觉得还是有点别扭。

    作者回复: 哈哈对,除非是老项目维护,新项目最好使用 python 3 来构建,确定好规范后就可以大胆 coding,不用太担心兼容性问题。

    2019-06-08
    3
  • 秋官萧
    export PYTHONPATH="/home/ubuntu/workspace/your_projects"

    在windows系统 中 亲测无效 T_T

    作者回复: windows 的文件系统和 Linux 不太相同,学计算机科学还是尽早切换到 linux 系统吧

    2019-06-07
    1
    3
  • Cynthia🌸
    1. 在 Python 3 规范中,__init__.py 并不是必须的,这只是python2的规范。
    2. 项目中,import可以用相对路径,是pycharm的黑魔法。自己也可以通过虚拟环境配置path实现。强烈建议一个项目用一个虚拟环境以保持纯净!
    3. import在导入时会把暴露在外面的代码都执行一遍,因此不想执行的话,请加上 if __main__ 的条件判断。
    2019-07-02
    2
  • Geek_59f23e
    class_utils.py那儿应该是reversed吧,而不是reverse。

    作者回复: 多谢,是 reversed.

    2019-06-08
    2
  • zjlyyq
    我自己试了下:实际上PyCharm在程序执行的时候会将项目根目录的绝对路径以及当前执行的文件所在的绝对路径一起加到sys.path里,所以无论怎么执行都能找到模块
    2019-09-01
    1
  • lyt
    老师您好,Pycharm是什么呢?Pytorch,tensor这些框架都有什么不同
    2019-08-08
    1
  • mercy
    老师,类实例化成对象后,直接把对象当成函数调用的做法叫什么呢?
    2019-07-31
    1
    1
  • Geek_66525b
    如果使用conda, 怎么达到和Virtualenv同样的效果呢?
    2019-06-26
    1
  • 乘坐Tornado的线程魔法师
    老师,对于文中“项目模块化”的段落,有关二维矩阵相乘运算,您给的例子是行与列维度相同的,所以代码运行没有问题;如果您试一下3 x 2的矩阵与2 x 3的矩阵相乘, 例如:[[1, 2], [3, 4], [5, 6]] 与[[5, 6, 7], [7, 8, 9]],代码则会报错(索引溢出)。

    我改写了一下mat_nul方法:
    def mat_mul(matrix_1: Matrix, matrix_2: Matrix):
        assert matrix_1.m == matrix_2.n
        n, s, m = matrix_1.n, matrix_1.m, matrix_2.m
        result = [[0 for _ in range(m)] for _ in range(n)]
        for i in range(n):
            for j in range(s):
                for k in range(m):
                    print(i, j, k)
                    result[i][k] += matrix_1.data[i][j] * matrix_2.data[j][k]
        return Matrix(result)

    我自测通过,请您帮忙验证下!不胜感激!
    2019-06-15
    1
  • Kuzaman
    老师,python虚拟环境使用【virtualenvwrapper-win、virtualenv】,我用的是sublimetext3它只能配置编译环境的位置(我在sublime的tools--build system--python-venv01指向了虚拟环境Venv01),但是我无法达到老师文章说的:“这样,每次你通过 activate 激活这个运行时环境的时候,,它就会自动将项目的根目录添加到搜索路径中去。”
    2019-06-11
    1
  • 更好的做自己
    老师,我使用anaconda配置的virtual env,在相应virtual env中找到的activate文件后加上PYTHONPATH,使用source activate激活virtual env后,echo $PYTHONPATH没有值输出,运行python main.py,依然会报ModuleNotFoundError: No module named 'proto'这个错误,使用原生Python解释器和mkvirtualenv能够成功,这是anaconda在activate时的机制不同吗?希望老师解答一下
    2019-06-09
    1
  • lllong33
    减少 from .. import .. 的使用,可以有效防止命名冲突。使用 imoprt 相当于加上一层标识
    2019-12-05
  • enjoylearning
    不带init.py,想用setup.py打包就不行了,这点很头疼
    2019-12-01
  • Paul Shan
    树状结构是大多数项目的组织方式,树状结构本身不复杂,从根节点到每个节点有唯一路径,这条路径可以用一致的方式来引用文件。树状结构可以表达的文件上限是层数的指数,对于大型项目也没问题。如果目录是线性结构,文件一多,查找就费力。文件直接的调用如果用相对路径,这就相当于在树状的结构中引入了中间节点的边,几乎让树成图,复杂度大大增加。
    2019-11-15
收起评论
60
返回
顶部