Python一些小技巧
Python一些小技巧
python上手简单,但有很多“语法糖”或者说很细微但对编程很有用的细节,下面整理如下:
P.S. 本书内容来自《写给程序员的Python教程》
What is 语法糖
语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
善用help()模块
help(函数名)可以让我们取得该函数的基本用途,是一个很重要的模块工具。
在编写时要写好docstrings
def function1():
"""一句话描述
Args:
参数名:参数解释
Returns:
返回值
Raises:
可能返回的错误
"""
之所以要编写好docstrings,在调用help(函数名)时会一起显示出来
注意文件编码
可以利用字符串的decode和encode来进行编码
现有一字符串str_o
str_o = str_o.encode('utf-8')
str_o = str_o.decode('gbk')
这样的操作可以解决大量编码问题
模块化编程
在导入一个模块时,如果模块中的某些语句没有封装成函数,那么就会被在导入的同时执行,有解决方案如下:
将函数封装
def function_name():
pass
将主函数加以限制,这时只有当该模块为主函数(运行的入口函数)时,代码才会被运行
if __name__ == '__main__':
pass
默认参数值
def function2(a, b=2):
print(a)
print(b)
如果是默认参数,那要放在a后面
异常
基本语法
try:
pass
except 错误类型:
pass
其中错误类型既可以是一个,又可以是一个可迭代对象
raise
raise ValueError()
无参数的raise会简单地重抛当前正在处理的异常
或者是直接抛出一个异常对象
demo:
import sys
import math
def sqrt_new(x):
if x < 0:
raise ValueError("Canot compute negative ")
return math.sqrt(x)
def main():
try:
print(sqrt_new(9))
print(sqrt_new(-1))
except ValueError as e:
print(e, file=sys.stderr)
main()
这种方法只是用来说明raise的用法,并不是真正使用
真正使用的原则是先等程序犯错误,然后才进行相应的应对处理
finally的使用
try:
...
except:
...
finally:
...
有时,无论成不成功,都要最后“回复现场”,此时finally就显得很重要
迭代器和生成器
对于一个可迭代对象,可以通过初始化迭代器来访问
iterable = ['Spring', 'Summer', 'Autumn', 'Winter']
iterator = iter(iterable)
此时
next(iterator)
# Spring
next(iterator)
# Summer
next(iterator)
# Autumn
next(iterator)
# Winter
next(iterator)
# StopIteration Error
每一次调用next(),都会出现列表中的一项,在最后会出现如下的错误
生成器是一类特殊的迭代器,其重点是yield关键词,遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行(第一次是从头开始运行)。
例子:如下是一个生成斐波那契数列的生成器的例子
def range2(m, n):
i = m
while i < n:
yield i
i = i + 1
上面就是重写了一下range函数
>>> def fibonacci(n): # 生成器函数 - 斐波那契
... a, b, counter = 0, 1, 0
... while True:
... if (counter > n):
... return
... yield a
... a, b = b, a + b
... counter += 1
...
>>>
>>> f = fibonacci(10)
>>> next(f)
0
>>> next(f)
1
>>> next(f)
1
>>> next(f)
2
>>> next(f)
3
>>> next(f)
5
>>> next(f)
8
>>> next(f)
13
>>> next(f)
21
>>> next(f)
34
>>> next(f)
55
>>> next(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
为什么要用迭代器?
- 低内存消耗
sum(x*x for x in range(1, 10000001))
所需的时间,所用的内存都要远小于用列表进行同样的操作
个人感受:
只有访问时才计算出所需的值,大量减少了"闲置时间"
any和all
用于可迭代的布尔函数
any相当与把序列中的元素全部并,all为全部交
any([False ,False, True])
#True
all([False, False, True])
# False
对文件的读写
f = open('test.txt', mode = 'a', encoding='utf-8')
open函数有三个重要的参数
部分读取文件的技巧
f.readline()
可以读取一行,在文件太大时可以利用这个来
f.readlines()
生成一个由行组成的列表
with open(...) as f:
...
这是一个必要的文件,在你不确定时用with可以避免错误,实际上的with函数十分复杂,需要大量的同类代码块才能替代,所以说用with是必要的。
利用Python库进行单元测试
unitest由三个主要部分组成:
测试用例
将一组相关的测试方法组合在一起
固件
装配:确保在测试运行之前测试环境处于预期状态
拆卸:在测试运行后清理环境,通常是释放资源
断言
测试方法内部的特定检查
demo:
如果要测试一个analyze函数,可以这样编写代码
# text_analyzer.py
import unittest
class TextAnalysisTests(unittest.TestCase):
def test_function_runs(self):
analyze()
if __name__ == '__main__':
unittest.main()
得到这样的结果
E
======================================================================
ERROR: test_function_runs (__main__.TextAnalysisTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\笑云博文\Desktop\fff.py", line 6, in test_function_runs
analyze()
NameError: name 'analyze' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.006s
FAILED (errors=1)
若加上定义,则变成
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
固件相当于文件的试验品,但这些试验样例在测试结束后就没用了,这时要使用setUp和tearDown来进行
断言
断言包含判断结果正确性的断言和判断错误正确性的断言,注意下面的代码
import unittest
import os
class TextAnalysisTests(unittest.TestCase):
def test_function_runs(self): # 这里是检测是否能正常运行
analyze(self.filename)
def test_content(self): # 这里是检查内容是否一致
self.assertEqual(analyze(self.filename), 'lalal')
def test_error(self):
with self.assertRaises(IOError): #注意这里with代码的用法
analyze('ddd')
def setUp(self):
self.filename = 'eee.txt'
with open(self.filename, 'w') as f:
f.write('lalala')
def tearDown(self):
try:
os.remove(self.filename)
except OSERROR:
pass
def analyze(filename):
string_test = ''
with open(filename, 'r') as f:
string_test = f.readline()
return string_test
if __name__ == '__main__':
unittest.main()
结果如下所示:
F..
======================================================================
FAIL: test_content (__main__.TextAnalysisTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\笑云博文\Desktop\fff.py", line 11, in test_content
self.assertEqual(analyze(self.filename), 'lalal')
AssertionError: 'lalala' != 'lalal'
- lalala
? -
+ lalal
----------------------------------------------------------------------
Ran 3 tests in 0.012s
FAILED (failures=1)
这是常用的驱动脚本

浙公网安备 33010602011771号