写在前面
不知不觉作为一名 Python 开发工程师 也有好几年的时间了,对于 Python 总想写点总结,却又不知从何开始。随着公司项目不断转向 Java,我隐约的觉得 Python 的生涯也将迎来终结,所以近期抽个空下这篇关于 Python 的一些总结。
正文开始
先看一个 Python3 Cheat Sheet,忘了哪里收藏的图了- 侵删。
关于版本的选择
截至 2021 年 7 月 7 日 最新的 Python 版本为 Python 3.9.6
,建议小伙伴直接上手最新版的 Python 就好了。如果你有接手之前版本的 Python 项目,其实问题也不大,只是在小部分语法上会有变化。至于入门、学习 Python 的小伙伴推荐浏览官方网站。
需要注意的是 2020 年 1 月 1 日,官方宣布停止 Python2 的更新。
关于 Pythonic
用于赞扬符合 Python 风格的代码,即充分利用 Python 语言的特性,写出简洁明了、可读性强,通常运行速度也快的代码。还指 API 符合 Python 高手的编程方式。
Pythonic 是 Python 的开发者描述那种符合特定风格的代码。这种 Pythonic 风格,既不是非常严密的规范,也不是由编译器强加给开发者的规则。而是大家在使用Python语言协同工作的过程中逐渐形成的习惯Python开发者不喜欢复杂的事物,他们崇尚直观、简洁而又易读的代码。
关于 Ipython
IPython是一种基于Python的交互式解释器。相较于本地的Python Shell,IPython提供了更为强大的编辑和交互功能。
建议全体小伙伴在学习测试 Python 代码时候使用 Ipython。可以快速验证结果以及实现想法,Jupyter 就是基于 Ipython 开发的一个 Web端交互式开发工具。
如果你是 Web 开发 Ipython 可以满足日常需求;如果你是数据科学家,直接使用 Jupyter,大多数数据科学家 将 Jupyter 作为首选的开发工具使用。
关于 列表/字典/集合 推导式
熟练使用各种推导式,可以解决多数 map/reduce/filter
解决的问题。
# 过滤 0-9 中能被3整除的数字``[ i for i in range(10) if i % 3 == 0] # [0, 3, 6, 9]`` ``my_list = ['apple', 'banana', 'grapes', 'pear']`` ``# 快速生成下标+元素的字典``{ k:v for k,v in enumerate(my_list)} # {0: 'apple', 1: 'banana', 2: 'grapes', 3: 'pear'}`` ``# 快速获取列表中字符串长度的值``{len(s) for s in ['a','is','with','if','file','exception']} # {1, 2, 4, 9}`` ``# 生成器推导式与列表推导式使用方式一致,不过对于生成器推导式返回值为 生成器对象``(i for i in range(10)) # <generator object <genexpr> at 0x103d808e0>
数据量较大的序列中不建议使用列表推导式,推荐使用生成器推导式;利用生成器推导式懒加载特性处理大数据。
关于生成器,本质上也是迭代器,不过它比较特殊。列表是一次性将所有数字存到对象中,生成器是什么时候需要,才什么时候生成。
a = [i for i in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]``b = (i for i in range(10)) # <generator object <genexpr> at 0x102a22888>`` ``# 在 for 循环语句下使用一致,在获取元素时 生成器不支持下标直接获取,需要调用 next 函数依次获取`` ``# 生成器获取数据``next(b)
PS:for 循环语句内部同时列表、生成器等迭代器的访问,所以在 for 循环表现一致。
关于循环中获取元素索引
强烈推荐 使用 enumerate
,Python 内置 enumerate
可以把各种迭代器包装成生成器,生成器每次调用返回元素下标 + 元素对象。
my_list = ['apple', 'banana', 'grapes', 'pear']`` ``# 不推荐``for i in range(len(my_list)):` `print(i, my_list[i])`` ``# 推荐``for counter, value in enumerate(my_list):` `print(counter, value)
关于字典的合并
期望是存在两个字典,合并并生成新的字典
-
**
解构参数的方式 -
字典
update
方法
a_dict = {"a":1, "b":1}``b_dict = {"b":2, "c":2}`` ``# 参数解构方式``c_dict = {**a_dict, **b_dict}`` ``# 字典 update 方法``c_dict = {}``c_dict.update(a_dict)``c_dict.update(b_dict)`` ``# 其他方式``import itertools``c_dict = dict(itertools.chain(a_dict.items(), b_dict.items()))`` ``# 上诉合并后的字典,重复的 key 后者会覆盖前者``# 下面的方式是优先使用前者``from collections import ChainMap``c_dict = ChainMap(a_dict, b_dict
注意:一个 ChainMap 接受多个字典并将它们在逻辑上变为一个字典。然而,这些字典并不是真的合并在一起了, ChainMap 类只是在内部创建了一个容纳这些字典的列表 并重新定义了一些常见的字典操作来遍历这个列表。
关于闭包/装饰器
一个有趣的闭包函数 实现函数加法函数调用方式为 add(1)(2)
并且记录函数调用次数(面试被问到过),需要注意的是:
- 内部函数想使用外部函数的局部变量 内部函数内需要用**
nonlocal
声明。**
def add(a):` `count = 1`` ` `def fun(b):` `nonlocal count` `print(f"func called count {count}")` `count += 1` `return a + b` `return fun`` ``add(1)(2) # 3
如下实现一个支持参数的记录日志功能的装饰器,需要注意的是:
- 内部函数 需要被**
@wraps(func)
修饰,目的是保留原函数的信息。**
from functools import wraps, partial``import logging`` ``def logged(func=None, *, level=logging.DEBUG, name=None, message=None):` `if func is None:` `return partial(logged, level=level, name=name, message=message)`` ` `logname = name if name else func.__module__` `log = logging.getLogger(logname)` `logmsg = message if message else func.__name__`` ` `@wraps(func)` `def wrapper(*args, **kwargs):` `log.log(level, logmsg)` `return func(*args, **kwargs)`` ` `return wrapper`` ``# Example use``@logged``def add(x, y):` `return x + y`` ``@logged(level=logging.CRITICAL, name='example')``def spam():` `print('Spam!')
关于大文件的读取
比较经典的面试题就会考察 Python 的文件读取,比如下面的题目:
如何在一个内存小于 8 GB 的电脑上, 读取 文件大小为 8 GB 的文件 ?
- 方案一 详情见 Stackoverflow :
手动实现文件读取的迭代器,并指定每次文件迭代的大小
def read_in_chunks(file_object, chunk_size=1024):` `"""Lazy function (generator) to read a file piece by piece.` `Default chunk size: 1k."""` `while True:` `data = file_object.read(chunk_size)` `if not data:` `break` `yield data`` `` ``with open('really_big_file.dat', "rb") as f:` `for piece in read_in_chunks(f):` `# <do something with piece>` `process(piece)
使用
with
语句块,会自动处理文件的 打开、关闭、异常;for line in f
为一个迭代器,会自动的采用缓冲IO和内存管理,所以你不必担心大文件。
`with open("file_name", "rb") as f:` `for line in f:` `# <do something with line>` `process(line)`
总结:两种方式都是使用迭代器,懒加载的方式去分块处理文件 ps:二进制的方式打开文件,读取速度更快。
关于一些标准库
下面列举一些个人认为有意思的库,更多的内容可以自行查看源码。
collections
提供额外的数据类型:
-
namedtuple 生成可以使用名字来访问元素内容的tuple子类
-
deque 双端队列,可以加速从另一侧追加和推出对象
-
counter 计数器,主要用来计数
-
orderedDict 有序字典
-
defaultdict 带有默认值的字典
from collections import *` `# orderedDict 以理解为有序的dict,底层源码是通过双向链表来实现``o = OrderedDict()``o["x"] = 1``print(o) # OrderedDict([('x', 1)])`` ``# 理解为给tuple的元素命名``rectangle = namedtuple("rectangle", ["a", "b"])``r1 = rectangle(3,4)``print(r1) # rectangle(a=3, b=4)``print(r1.a) # 3`` ``# ...` ` ``# Counter 这个很有用,可以给列表元素计数;类似功能有词频统计``wc = Counter("hello world")``print(wc) # Counter({'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1})``print(wc["h"]) # 1
heapq
python 实现的堆队列
# 有这么个面试题,求一数组的前K大个元素。用 heapq 两行代码就能实现``import heapq``nums = [14, 20, 5, 28, 1, 21, 6, 12, 27, 19]``# 前K个元素``heapq.nlargest(3, nums) # [28, 27, 21]``heapq.nsmallest(3, nums) # [1, 5, 6]
关于一些书籍的推荐
由于有些书没有公开的电子版,这里就不放链接了。
-
Python3-Cookbook
-
流畅的 Python
-
Python 3 标准库
-
编写高质量Python代码的59个有效方法
再多说一句,多看官网文档。
以上就是“入门必看:写给 Python 小伙伴的一些建议”的全部内容,希望对你有所帮助。
关于Python技术储备
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、Python练习题
检查学习结果。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
最后祝大家天天进步!!
上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。