py za

[原创]&[旧贴] 零敲碎打 --- Python新手不完全FAQ

2008-12-08 12:11:34
按:曾在2006年发表于公司内部刊物,有删节。


零敲碎打 --- Python新手不完全FAQ


如果''国家的正义在于三种人各司其职''(《理想国》-- 柏拉图),那么对程序员来说,编码的正义或许就在于各种语言各司其职。掌握一门脚本语言对提高我们的工作效率和质量是有很大帮助的,这里向大家严重推荐Python语言。

本文是笔者在学习和使用Python时所做笔记的整理,希望这篇FAQ能够节省大家学习Python的时间和精力,同时希望Python能够给大家的工作和生活带来更高的效率。

关于
1.1 什么是Python?
    Python 是一门语法简洁优美,面向对象,内置高级数据结构,支持模块和包,支持多种平台,可扩展的解释型通用编程语言。
安装好Python之后,交互环境下输入:
>>>import this
可以看到一段Python自己的哲学。

1.2 如何开始学习Python?
    建议的学习流程:
基本流程控制语句->类,函数的写法->内置高级数据类型(列表,元组,字典,串)->根据需要学习标准库中的模块或者其他模块/架构

调试
2.1 如何调试我的Python脚本?
    你需要标准库中的pdb模块。
只需在代码中加入:
...
import pdb # 引入pdb模块
...
pdb.set_trace() # 在需要设断点的地方加入这句~
...
如此这般,程序运行至断点出会停住。然后,如果熟悉GDB那么一切都好办了,如果不熟悉,请学习GDB~,因为pdb的调试命令基本都是模仿GDB的,看名字就知道了^^。

文件
3.1 如何拷贝/移动文件?
    有几种方法可以做到这件事,最简单的是使用shutil模块:
import shutil # 引入shutil模块
shutil.copyfile('./a.txt','../xx/b.txt') # 拷贝文件
shutil.move('../build/a.txt','./debug/') # 移动文件

3.2 如何遍历目录?
  os模块中有两个函数可以方便的遍历目录:
os.walk(top, dirs, fnames)
其中:
top 为当前目录相对路径
dirs 列表,保存当前目录下所有子目录名
fnames 列表,当前目录下所有文件名

os.path.walk(top, func, arg)
其中:
top 所要遍历的目录名
func 回调函数,格式为 func(arg, dirname, fnames)
arg 回调函数参数,如果不需要其他的参数,就传个None好了

3.3 如何作文件/串压缩?
  zlib模块和gzip模块正是你所需要的。
zlib.compress(str) # 压缩字符串str,返回压缩后的串
zlib.decompress(str) # 上面函数的反函数
gzip.zlib.compress(str) # 算法不同,其余同上~
gzip.zlib.decompress(str)
    如果需要对文件压缩/解压,需要使用 zipfile 模块,tgz格式的文件需要配合tarfile模块。

3.4 如何查看串的16进制值?
    使用binascii模块
binascii.b2a_hex(str) # 返回一个串中每个字节的16进制ASCII值
binascii.a2b_hex(str) # 以上的反函数,给出一串16进制值,返回相应的字符串

3.5 如何获得文件信息?
os.stat(fname) # 返回文件时间,大小,所在驱动器等信息

3.6 如何作文件映射?
    使用标准库中的mmap模块。
import mmap
mmap.mmap(fn, size) # fn 为文件号,size为buffer大小,返回映射后的buffer
例:
import mmap
import os
fi = open('./tmp.dat', 'r+') # 注意,打开方式为读写
c = mmap.mmap(fi.fileno(), os.stat(fi.name).st_size) # 映射
print c.readline() # 映射的buffer与普通文件操作方法是相同的

    StringIO模块,兴许你也会感兴趣。可以利用这个模块在内存中虚拟一个文件。
例:
import StringIO # 引入所需模块
f = StringIO.StringIO() # 建立一个虚拟文件
f.write('hello, python') # 与普通文件的操作方法是相同的
f.seek(0)
print f.read()

    由于是保存在内存中,所以程序退出后就不存在了,需要的话别忘了向磁盘写一份~

编码
4.1 为什么要讨论编码问题?
    有人抱怨 Python 对中文的支持不好,实际上是在使用中忽略了编码的问题。许多库函数默认的编码是Unicode,而标准输入输出环境或者脚本的源码是由都不是 Unicode ,如此,使用的时候就会发现一堆乱码出现在命令行或者窗体上...实际上Python对于各种编码的处理是很出色的,我们只需要简单了解一下。

4.2 如何获得当前标准输入输出的编码?
    通过sys模块的如下两个属性
sys.stdout.encoding
sys.stdin.encoding
  通常,中文Windows下面得到的结果是cp936。

4.3 如何将串的编码转换到我需要的编码?
    先转换为unicode,再转换为具体的编码,因为Python内部的编码是Unicode。
字符串类型的量有两个函数:
str.decode(encoding) # 将字符串的内容按指定编码解码
str.encode(encoding) # 将字符串的内容按指定编码编码
例:
>>>mystr = 'Hello, 世界~' # 以Windows为例,此时mystr的编码为'cp936'
>>>mystr.decode('cp936') # mystr 的内容按 'cp936' 解码的结果,以 Unicode 形式返回。
u'Hello, \u4e16\u754c\uff5e'
>>>mystr.encode('utf8') # mystr 的内容按 'utf8' 编码,结果自然以 'utf8' 形式返回 -___-。

注意:
    1.写文件时不可以用 unicode,要声明一种编码如 utf8/big5/gbk...
    2.utf 系列编码可以包容简繁,但是,简繁之间不能通过 utf 为中介字字转换,因为同一个字的简繁体对应的是 utf 中不同的编码,不知说清楚了没 - -~!

4.4 脚本原文件的编码如何指定呢?
    只要在文件开头第二行注释中声明一下就行了。
官方文档中是这样说地:
More precisely, the first or second line must match the regular
expression "coding[:=]\s*([-\w.]+)".
因此通过上述的正则表达式就可以知道:
coding后面为:或=均可。根据上面的正则式可以推出几种正确的写法,找一种喜欢的吧。
    coding:cp936
    coding=cp936
至于前面有什么都无所谓。
例:
#!/usr/bin/python
# coding=utf8
...

标准输入输出
5.1 在屏幕上输出数据
import sys
def pyout(str):
   sys.stdout.write(str)
   sys.stdout.flush()
>>>pyout(something)
>>>pyout('\r') # 清除标准输出的当前行
当然,也可以用简单的 print...

5.2 怀念 C 中的格式化输出?
    字符串配合%符。
例:
>>>'%s %o %x %%'%('test', 16, 16)
'test 20 10 %'

5.3 得到命令的结果
#得到控制台程序输出
import os
c = os.popen("dir").read()
#得到窗口程序的标准输出
import commands
x = commands.getoutput('ls')

语法杂技
6.1 怎样显式释放内存,如何防止内存泄露?
    嗯,请相信Python的内存回收机制,您大可以发挥一下主观能动性,构造一个(您认为)会产生内存泄露的程序,观察一下结果是否和设想相同。
    实际上当一个引用不再需要时,只要 del 掉即可。
    对于像笔者这样每次走出家门100米开外都要回来查看一下是否锁了门的强迫症疑似者,请使用gc模块。
import gc
...
gc.collect() # 返回所有被清除的unreachable对象个数。

6.2 怎样复制可以得到一个对象的全部内容,而不仅仅是其引用?
    使用 copy 模块。
copy.deepcopy(...) # 返回目标对象的全部内容

6.3 列表生成式
    提一下,这个语法太方便了,详细请参考官方文档。
例:
a = range(10) # 生成数字 0~9 列表
a = [i**2 for i in a if i % 2 == 0] # 这下a变成9以内偶数平方的列表了。

6.4 内建函数
   dir()     # 列出对象方法和属性
   help()    # 列出对象的说明文档
   del       # 删除对象引用
   type()    # 对象类型
   id()      # 对象的唯一标识

6.5 内建常数
   None # 类似 C++ 中的 null
   True # 注意大小写!
   False # 同上~

6.6 一行之内已经难以容纳我的一句代码了~!
    如果您希望在一行之中写多句代码,请使用';'号。(众读者:歹人...)
    如果希望使用多行写一句代码,请使用续行符'\'或者括号。
续行符和括号的例子:
# 下面是一句比较长的代码
a = ''.join([chr(ord(i) - 2) for i in   '|jg|jqpiokocvcklkcpfcpng000'])
# 下面这两行是加了续行符的。
# 注意,续行符后除了回车不能接任何字符,不要在续行符后写注释。
a = ''.join([chr(ord(i) - 2) for i in   '|jg|jqpioko\
cvcklkcpfcpng000'])
# 下面两行是使用括号续行的,续多少行都行,同样不要在断行处写注释
# 凡是圆括号()、方括号[]、花括号{}及三引号字符串内的部分均不需要使用续行符。
a = ''.join([chr(ord(
i) - 2) for i in  
'|jg|jqpiokocvcklkcpfcpng000'])

推荐工具
pysh,*nix下面有csh,Python爱好者有跨平台的pysh。pysh是Python编写的shell,兼容*nix shell操作方式,并且可以方便的以交互方式编写python脚本。现在我已经基本上用pysh取代cmd和sh了...这种感觉真好,我命苦的小拇指终于得到解脱了~~。

ctags,python模块,已被加入Python2.5的标准库。这个模块提供了Python在Linux和Windows平台下调用动态链接库的能力...想象一下吧,如果你的程序同时具有C++的运行效率和Python的开发效率...>_<

最后
限于篇幅,本文到此为止,希望大家了解脚本,学习脚本,让我们的工作更有效率,让我们的生命更有意义!

(
另:
如果坚持/习惯在写给自己用的工具的时候,用C/C++写遍历目录的代码,您是老张;如果公共目录下有一堆Python书籍,您是David;如果问怎么把.py的文件编译成.exe的,您是童童;如果觉得'END'比'\t'优雅,您是桑哥;如果觉得Python其实是'密林',您是阿楠;
鉴定完毕,欢迎拍砖!
)

原文地址:https://www.cnblogs.com/lexus/p/1845087.html