概述
这里是记录一些本人在开发过程中遇到的一些细节及代码优化问题,希望与君共勉。
版权说明
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Coding-Naga
发表日期: 2016年3月17日
链接:http://blog.csdn.net/lemon_tree12138/article/details/50854673
来源:CSDN
目录
- 版权说明
- 目录
- 奇技淫巧
- Python代码获取命令行输出
- 不要将表达式作为函数的默认参数
- 指定异常代码块exception block的参数
- 在遍历列表时更改列表
- 更优雅地打印出JSON
- __init__py的功能
- Ref
奇技淫巧
1. Python代码获取命令行输出
这里可以通过subprocess模块中的Popen, PIPE来实现。
比如有这如下代码,就可以尝试捕获控制台输出的文本信息:
from subprocess import Popen, PIPE
label = "Hello, Shell."
print(label)
f = Popen(("python", "catch_output.py"), stdout=PIPE).stdout
print("Catch Output: {0}".format(f.readline()))
上面的代码中我们可以打印出自身的控制台输出,还有通过捕获输出获得的输出信息。如下:
Hello, Shell.
Catch Output: Hello, Shell.
2. 不要将表达式作为函数的默认参数
在Python有一个比较基础也是比较重要的特性,那就是在python的函数中,我们可以给参数指定一个默认的值。但是,这是有一个小小的陷阱。对于新手来说可能会经常引起困扰,比如我们像下面这样编写python代码:
def test_args(array=[]):
array.append("Bob")
return array
以上的代码中正常情况下,是没有什么问题的,因为的的确确可以打印出“[Bob]”。可是,问题是出现在我们重复的调用上。怎么说?就以上面的test_args()方法,我们进行三次重复调用。打印的结果却是:
[‘Bob‘]
[‘Bob‘, ‘Bob‘]
[‘Bob‘, ‘Bob‘, ‘Bob‘]
WTF!
这是怎么会回事呢?因为,可选参数默认值的设置在Python中只会被执行一次。
怎么来理解?很简单,也就是我们的参数默认值只有在对此函数进行定义,并且在函数调用的时候不传递此参数的值的时候,才被认为需要对其进行默认值的赋值。
想要修改此函数也很简单,代码如下:
def test_args(array=None):
if array is None:
array = []
array.append("Bob")
return array
3. 指定异常代码块(exception block)的参数
在python2.x中,我们知道可以使用逗号来进行异常参数的指定。如下:
def fun():
try:
print("Hello, Exception")
except Exception, e:
print(e)
pass
可是在python3.x中,这种写法却存在着语法上的错误。不过对于python2.x与python3.x来说,都可以使用as来进行指定。如下:
def fun():
try:
print("Hello, Exception")
except Exception as e:
print(e)
pass
所以,对于可能存在版本差异的项目来说,最好还是使用as来指定参数更为妥当。
4. 在遍历列表时更改列表
正常情况下我们很难在遍历列表的过程中能列表进行修改,这一条不仅在Python中适用,在Java中也存在着同样的规则。比如,如下的写法就会抛出一些异常。
def test_list_modify():
a = [0, 1, 2, 3, 4, 5, 6, 7, 8]
odd = lambda x: bool(x % 2)
for i in xrange(len(a)):
if odd(a[i]):
a.remove(i)
print(a)
上面的代码一定会抛出异常,异常如下所示:
Traceback (most recent call last):
File "E:/workspace/src/Python/Demo/SimpleDemo-python/test/test_demo.py", line 106, in <module>
test_list_modify()
File "E:/workspace/src/Python/Demo/SimpleDemo-python/test/test_demo.py", line 76, in test_list_modify
if odd(a[i]):
IndexError: list index out of range
原因也很容易找到,上面的代码中,我们尝试去修改列表的长度,这样会导致循环的过程中,访问数组的下标会超出修改后的列表长度。从而抛出以上异常信息。
不过,我们可以利用Python语言自身优雅的编程范式。修改后的代码如下:
def test_list_modify():
a = [0, 1, 2, 3, 4, 5, 6, 7, 8]
odd = lambda x: bool(x % 2)
a[:] = [n for n in a if not odd(n)]
print(a)
5. 更优雅地打印出JSON
在Python中,json模块为我们提供了非常好的json对象的打印接口——json.dumps()
当然json.dumps()中传入的是json这个对象,而不是原始的json字符串。想要实现将原始json字符串优雅地打印出来,我们可以对其进行二次封装。
- 通过json.loads()将json字符串转化成json对象;
- 通过json.dumps()将json字符串优雅地打印出来.
import json
json_data = "{\"status\": \"OK\", \"count\": 2, \"results\": [{\"age\": 27, \"name\": \"Oz\", \"lactose_intolerant\": true}," " {\"age\": 29, \"name\": \"Joe\", \"lactose_intolerant\": false}]}"
def parser():
json_obj = json.loads(json_data)
show(json_obj)
pass
def show(json_obj):
print(json.dumps(json_obj, indent=4))
pass
if __name__ == ‘__main__‘:
parser()
pass
打印的结果如下:
6. __init__.py的功能
有时我们需要向一个自定义模块中导入很多其他模块的内容,这样会让代码显得有一些臃肿。不过,好在我们可以通过__init__.py这个文件来解决这个问题。做法是将导入模块的代码放在__init__.py这个文件中,再在目标文件中导入__init__.py这一个模块中的全部内容即可。
在__init__.py中有如下代码:
import os
import time
import datetime as date
测试文件中的调用代码如下:
from __init__ import *
print(time.ctime())
print(date.date.day)
print(os.system("python test_init.py"))
当然,你也可以选择一个一个地导入,如下:
from __init__ import sys
from __init__ import getopt
from __init__ import pack
from __init__ import pehelp
from __init__ import PEParser
from __init__ import Signature
Ref
http://codingpy.com/article/top-10-mistakes-that-python-programmers-make/
http://www.vaikan.com/improving-your-python-productivity/