mirror of
https://github.com/beyondx/Notes.git
synced 2026-02-04 02:43:32 +08:00
Add New Notes
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:49:50+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第10章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
1、python解析器的参数:
|
||||
-i 当程序执行完毕后,进入交互模式。
|
||||
-O 优化模式
|
||||
-OO 进一步优化模式
|
||||
-v 详细现实
|
||||
-x 跳过py文件的第一行
|
||||
|
||||
2、另外,python会解析一些环境变量,例如:
|
||||
PYTHONPATH 模块搜索的路径,会被插入到 sys.path
|
||||
PYTHONIOENCODING 对于stdin、stdout和stdout的方式?
|
||||
PYTHONOPTIMIZE -O参数
|
||||
|
||||
3、当在命令行只输入python,不加任何py文件时,进入交互模式。>>>提示输入新的一行语句。…表示目前处于多行语句下。这些数值可以通过环境变量sys.ps1和sys.ps2来设置。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> print sys.ps1
|
||||
>>>
|
||||
>>> print sys.ps2
|
||||
...
|
||||
|
||||
4、上一次的计算结果用下划线“_”代替。
|
||||
|
||||
5、如何直接执行py脚本(而不加python)?类似于shell,在第一行加入python的位置指令。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
例如test.py文件
|
||||
#!/usr/bin/env python
|
||||
......
|
||||
|
||||
执行时:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
chmod u+x test.py
|
||||
./test.py
|
||||
|
||||
6、第三方包和模块路径:sys.path,此外还有site目录,也在sys.path中记录了。
|
||||
|
||||
7、在安装包时,可以只将其安装在用户目录下,例如~/.local或者~/.local/lib/python2.x/site-packages,这可以通过python setup.py install –user来完成。
|
||||
|
||||
8、需要使用未来版本中的,但当前又不支持的功能,通过future:
|
||||
from __future__ import division
|
||||
|
||||
9、当有未捕获的SystemExit异常时,或者信号SIGTERM,SIGHUP时,会释放所有对象的引用和命名空间,如果有调用__del__()。
|
||||
但很多时候,__del__()并不会被调用,我们可以自己编写释放资源的函数,并利用atexit模块,在退出事件上注册它。这可以保证:在退出时一定会执行cleanup()
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import atexit
|
||||
|
||||
def cleanup():
|
||||
print "Exiting..."
|
||||
#Do something
|
||||
#close(f)
|
||||
#...
|
||||
|
||||
atexit.register(cleanup)
|
||||
|
||||
执行:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
python ./cln.py
|
||||
|
||||
Exiting...
|
||||
|
||||
10、也可以使用os._exit(status)来退出程序,它将直接使用exit()系统调用。liheyuan@cliheyuan@coder4-pc:/media/WIN7/Documents and Settings/liheyuan/Desktop$ iconv -f gbk -t utf8 ./python第10章.txt
|
||||
1、python解析器的参数:
|
||||
-i 当程序执行完毕后,进入交互模式。
|
||||
-O 优化模式
|
||||
-OO 进一步优化模式
|
||||
-v 详细现实
|
||||
-x 跳过py文件的第一行
|
||||
|
||||
2、另外,python会解析一些环境变量,例如:
|
||||
PYTHONPATH 模块搜索的路径,会被插入到 sys.path
|
||||
PYTHONIOENCODING 对于stdin、stdout和stdout的方式?
|
||||
PYTHONOPTIMIZE -O参数
|
||||
|
||||
3、当在命令行只输入python,不加任何py文件时,进入交互模式。>>>提示输入新的一行语句。…表示目前处于多行语句下。这些数值可以通过环境变量sys.ps1和sys.ps2来设置。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> print sys.ps1
|
||||
>>>
|
||||
>>> print sys.ps2
|
||||
...
|
||||
|
||||
4、上一次的计算结果用下划线“_”代替。
|
||||
|
||||
5、如何直接执行py脚本(而不加python)?类似于shell,在第一行加入python的位置指令。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
例如test.py文件
|
||||
#!/usr/bin/env python
|
||||
......
|
||||
|
||||
执行时:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
chmod u+x test.py
|
||||
./test.py
|
||||
|
||||
6、第三方包和模块路径:sys.path,此外还有site目录,也在sys.path中记录了。
|
||||
|
||||
7、在安装包时,可以只将其安装在用户目录下,例如~/.local或者~/.local/lib/python2.x/site-packages,这可以通过python setup.py install –user来完成。
|
||||
|
||||
8、需要使用未来版本中的,但当前又不支持的功能,通过future:
|
||||
from __future__ import division
|
||||
|
||||
9、当有未捕获的SystemExit异常时,或者信号SIGTERM,SIGHUP时,会释放所有对象的引用和命名空间,如果有调用__del__()。
|
||||
但很多时候,__del__()并不会被调用,我们可以自己编写释放资源的函数,并利用atexit模块,在退出事件上注册它。这可以保证:在退出时一定会执行cleanup()
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import atexit
|
||||
|
||||
def cleanup():
|
||||
print "Exiting..."
|
||||
#Do something
|
||||
#close(f)
|
||||
#...
|
||||
|
||||
atexit.register(cleanup)
|
||||
|
||||
执行:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
python ./cln.py
|
||||
|
||||
Exiting...
|
||||
|
||||
10、也可以使用os._exit(status)来退出程序,它将直接使用exit()系统调用。
|
||||
@@ -0,0 +1,53 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:50:11+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第11章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
本章主要介绍测试、调试和性能调优
|
||||
|
||||
1、C、Java等语言,都是预编译类型,编译器会阻止大部分的错误。而对于Python来说,仅当运行时才能知道错误。因此,发现错误的过程更麻烦一些。
|
||||
|
||||
2、函数、类等第一行常用三个引号的字符串来写注释docstring,如下:
|
||||
|
||||
def split(line,...):
|
||||
"""
|
||||
Split....
|
||||
|
||||
>>>split(...)
|
||||
>>>[...]
|
||||
"""
|
||||
|
||||
如上所示,doc中经常包含python交互shell的代码,用做测试用例。
|
||||
我们可以用docstring中的测试用例来做单元测试。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import split #被测试模块
|
||||
import doctest
|
||||
#根据docstring,返回unittest的通过和失败数量
|
||||
nfail, nsuccess = doctest.testmod(split)
|
||||
|
||||
3、上面用docstring来做测试的方法确实有点山寨,而且效率比较低,python也有unittest模块,其实和JUnit非常类似。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import split #被测试模块
|
||||
import unittest
|
||||
class TestSplit(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def tearDown(self):
|
||||
pass
|
||||
def testsimplestring(self):
|
||||
r = split.split("...")
|
||||
self.assertEqual(r,[......])
|
||||
|
||||
可以看到,和JUnit非常类似。其中assert还可以有:
|
||||
t.assert
|
||||
t.assertAlmostEqual(x,y,places) #在一定精度范围内匹配
|
||||
t.assertRaises(exc,callable…)
|
||||
等很多,需要时候看文档吧。
|
||||
|
||||
4、
|
||||
@@ -0,0 +1,162 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:51:25+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第12章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
1、有一些函数是不需要import的,因为他们存在于__buildin__模块下,这个模块是被默认引入的。在Python 3之后,更名为__buildins__,加了个s。
|
||||
|
||||
2、这些不需要import的称为内置函数。
|
||||
|
||||
3、一些内置函数/对象:
|
||||
|
||||
ascii(c):只在Python 3 可用!返回c对应的ascii字符,非ascii字符转化为对应的转义字符。
|
||||
basestring:Python 2 中Byte字符串和Unicode字符串的父类。
|
||||
bin(x):返回整数x的二进制表示。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> bin(1)
|
||||
'0b1'
|
||||
>>> bin(100)
|
||||
'0b1100100'
|
||||
|
||||
bool(x):将对象转化为布尔值。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#list非空,都为True
|
||||
>>> bool([10,20,0])
|
||||
True
|
||||
|
||||
#None对象为False
|
||||
>>> bool(None)
|
||||
False
|
||||
|
||||
bytearray:Byte String的类型。
|
||||
cmp(x, y):比较x和y,若xy返回正数,x==y返回0.
|
||||
compile(string,filename,mode):将字符串编译为Python对象。
|
||||
返回的是一个内部对象,只能被eval等执行。
|
||||
string:一行或者多行(\n换行)的代码
|
||||
filename:一般给”就可以
|
||||
mode:single(string为单行),exec(string为多行),eval(string为单行)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#编译有a和b的语境到对象x
|
||||
>>> x = compile("a=10\nb=[a,a,a]",'','exec')
|
||||
|
||||
#执行x对象
|
||||
>>> eval(x)
|
||||
|
||||
#打印b
|
||||
>>> print b
|
||||
[10, 10, 10]
|
||||
|
||||
4、一些内置函数:
|
||||
delattr(object,attr):相当于del object.attr,注意是删除对象的,不是dictionary的!
|
||||
eval(expr):如上所述,eval执行compile编译好的代码片段对象,相当于可动态载入吧。
|
||||
exec(expr):和eval类似,但它无返回值。
|
||||
filter(function,iterable):迭带过滤器,对迭带对象的每个元素应用function,如果返回True,则加入到返回结果中。
|
||||
如下:过滤所有x<5的。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> def func1(x):
|
||||
... return True if x<5 else False
|
||||
...
|
||||
>>> filter(func1,xrange(1,20))
|
||||
[1, 2, 3, 4]
|
||||
|
||||
5、一些内置函数:
|
||||
getattr(object,name):等同object.name
|
||||
hash(object):返回一个对应的Hash值(不是所有类型都可以,必须实现了__hash__())
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> hash(x)
|
||||
2119161711
|
||||
|
||||
iter(object):返回对象objet对应的迭带器。
|
||||
len(s):返回s的长度。
|
||||
locals():返回当前局部的变量。
|
||||
map(function,items):将function应用于每个items的对象上,并收集每次调用的返回结果。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#map函数和用法
|
||||
>>> def func2(x):
|
||||
... return -x
|
||||
...
|
||||
>>> map(func2,xrange(10))
|
||||
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
|
||||
|
||||
6、一些内置函数:
|
||||
max(s):返回s中最大值
|
||||
min(s):返回s中最小值
|
||||
next(s):返回迭带器的下一个
|
||||
object:所有对象的基类
|
||||
open(filename):打开一个对象并返回一个file-like object。
|
||||
ord(c):返回ascii/unicode字符对应的数字。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#ascii的数值
|
||||
>>> ord('c')
|
||||
99
|
||||
|
||||
#unicode的数值
|
||||
>>> ord(u'赫')
|
||||
36203
|
||||
|
||||
7、一些内置函数:
|
||||
|
||||
pow(x,y,[z]):x ** y,如果有z的话,x ** y % z,不知道是不是算RSA神马的会不会给力……
|
||||
试了试,好像还挺给力……
|
||||
range/xrange:返回连续数字的数组,一般推荐xrange吧,Python 3后统一为range了。
|
||||
round(x):将x约到最近一个10^x位。
|
||||
set(items):创建一个set
|
||||
slice(start,stop[,step]):返回一个slice对象??
|
||||
sorted(iterable):将iterxx排序后返回。
|
||||
vars(object):返回object的符号表?(其实就是返回__dict__属性)
|
||||
zip(s1,s2):把多个seq并联,返回(x1,x2)其中x1是s1中的,x2是s2中的。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> zip(xrange(5),["a","b","c","d","e"])
|
||||
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]
|
||||
|
||||
8、内置异常类
|
||||
BaseException:所有异常的基类。
|
||||
Exception:所有程序导致的异常的基类。
|
||||
ArithmeticError:算数异常基类,如OverflowError,ZeroDivisionError。
|
||||
EnvironmentError:环境导致的异常基类,如IOError和OSError。
|
||||
|
||||
9、异常的捕获:
|
||||
异常带属性args和message
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
try:
|
||||
xxxx
|
||||
except IOError as e:
|
||||
#handle exception
|
||||
print e.args
|
||||
pass
|
||||
|
||||
10、一些异常类
|
||||
EOFError:读到文件的末尾,不过只有input()和raw_input()会抛出这个异常。其他的read()和readline()一般以返回None或者空行做为反应。
|
||||
MemoryError:可恢复的内存错误?
|
||||
IOError:很常见了。带属性errno/strerror和filename。
|
||||
SystemExit:由sys.exit()函数发起,退出也可用os._exit()。
|
||||
|
||||
11、Python中也有Warning警告。
|
||||
|
||||
12、引入未来的模块/函数(future_builtins)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import future_builtins
|
||||
|
||||
本章完。
|
||||
@@ -0,0 +1,202 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:51:47+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第13章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
本章主要介绍了一些与Python运行时相关的模块。
|
||||
|
||||
1、atexit模块
|
||||
在真个Python解释器退出时,可以绑定若干钩子函数,通过atexit完成。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> def fun1():
|
||||
... print "hh"
|
||||
...
|
||||
>>> import atexit
|
||||
>>> atexit.register(fun1)
|
||||
<function fun1 at 0xb7707614>
|
||||
>>>
|
||||
#按Ctrl 和 D退出,会调用fun1
|
||||
hh
|
||||
|
||||
2、copy模块,可用于浅拷贝和深拷贝(copy.deepcopy)
|
||||
deepcopy(x [,visit]),其中visit用于递归深度,以防造成死循环。
|
||||
对象必须自己实现了__copy__(self_)和__deepcopy__(self,visit)才可以被浅、深拷贝。
|
||||
|
||||
3、gc模块:用于垃圾回收,这个应该很熟悉了。
|
||||
Python的垃圾回收分Generation,0,1和2。当在第0个Gen存活了x个周期(而没有到达refcount为0),则被放入1,以此类推到2。按照检查频率,0,1,2递减。以此来最大化平衡效率和回收效率。
|
||||
一些gc模块的函数:
|
||||
collect([generation]):全部执行一遍垃圾回收。
|
||||
get_count(object):获取某对象object的引用计数。
|
||||
disable():禁用gc
|
||||
garbage:一个list,存了一些不再使用,但存在循环引用的对象。
|
||||
set_threshold(threshold0,[threshold1,threshold2]):设置每隔多少个执行指令检查一次gc(引来一个gc周期)。
|
||||
|
||||
4、inspect模块,用于Python的属性、函数、字符串、文档、源代码等对应的Python的对象表示。
|
||||
几个术语:
|
||||
frame:代码+环境+stack。。。
|
||||
几个函数:
|
||||
isbuiltin(object):是否是内置函数。
|
||||
ismethod(object):是否是对象。
|
||||
trace([context]):返回stack等信息。
|
||||
|
||||
5、marshal模块,一个基础的对象序列化模块,很快但是功能单一,对数据类型支持也不太好。一般只支持基本类型。
|
||||
dump(value,file):把序列化写到file-object对象file中。
|
||||
dumps(value[,version]):对象序列化,并返回字符串。
|
||||
load(file):从file反序列化。
|
||||
loads(string):从字符串中饭序列化。
|
||||
|
||||
marshal在性能上很好,但是只支持数字、字符串、tuple、list、dictionary。而这几种支持的容器类型必须包含基本类型。也就是说不支持自定义object啦!
|
||||
|
||||
6、pickle,推荐使用的序列化方法,基本类型都支持了!
|
||||
dump、dumps、load、loads和marshal一样。
|
||||
如果要序列化多个对象,多次调用dump/dumps即可。
|
||||
有的对象不适合序列化,因为对内部状态没有标识,如file-object,network的socket等。
|
||||
|
||||
7、Pickler和Unpickler,是对pickle的对象化封装,需要的话可以翻翻文档。
|
||||
|
||||
8、sys模块:变量、解释器相关的函数。
|
||||
常用的属性:
|
||||
argv:cmd传入的参数,不用解释了吧~
|
||||
byteorder:返回机器的CPU的大小端’little’或者’big’,这个很实用,呵呵……
|
||||
copyright:返回版权信息?Python的。。
|
||||
maxsize:本机器上C语言integer支持的最大size(我的32位机器为2147483647)
|
||||
ps1,ps2:设置Python解释器的>>>和…
|
||||
winver,返回注册表的版本,windows可用。
|
||||
|
||||
常用的函数:
|
||||
_clear_type_cache():Python会Cache对象(和他们所在的模块),一般是1024个最近的。这个函数可以清空这个Cache。
|
||||
_current_frame():当前所处的frame。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#在python解释器中执行
|
||||
>>> sys._current_frames()
|
||||
{-1216022848: <frame object at 0x845458c>}
|
||||
|
||||
sys.exit([n]):引起一个SystemExit异常,然后退出,如果不需要引起异常,可以执行os._exit(n)。
|
||||
sys.getdefaultencoding():获取当前默认字符编码。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#貌似默认是ascii
|
||||
>>> import sys
|
||||
>>> sys.getdefaultencoding()
|
||||
'ascii'
|
||||
|
||||
sys.setprofile():设置这么一个profile,类似~/.bashrc只不过类型很随意,这么解释靠谱儿么?
|
||||
sys.getprofile():获取楼上设置的profile。
|
||||
|
||||
9、traceback模块:用于处理异常时候的,很管用。
|
||||
最常用的其实就是两个:
|
||||
traceback.print_exec(),直接把sys.exec(上次异常信息)格式化,并打印到stdout。
|
||||
traceback.format_exc(),和楼上类似,只不过是返回一个字符串。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#!/usr/bin/python
|
||||
|
||||
import traceback
|
||||
|
||||
def fun1():
|
||||
try:
|
||||
1/0
|
||||
except:
|
||||
traceback.print_exec()
|
||||
#print traceback.format_exc()
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
fun1()
|
||||
|
||||
10、types模块:就是Python对象的各种对应类型。
|
||||
|
||||
11、warnings模块:会”弹出“,但不会抛出异常,也不会阻碍程序继续运行。
|
||||
warning是可以过滤的,两种方法:
|
||||
(1)代码方式
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
warnings.filterwarnings(action="ignore",message=".*xxx.*",category=xxxx)
|
||||
|
||||
其中,action可以是ignore等。
|
||||
message是对哪些消息过滤,支持正则。
|
||||
category支持如下类型:
|
||||
Warning
|
||||
UserWarning
|
||||
DeprecationWarning
|
||||
SyntaxWarning
|
||||
RuntimeWarning
|
||||
FutureWarning
|
||||
(2)解释器的启动参数:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
python -Wignore:the \ regex:DeprecationWarning
|
||||
|
||||
resetwarnings():重置所有filter
|
||||
|
||||
12、weakref,弱引用模块。
|
||||
可以加一个引用,但不增加原对象的引用计数。
|
||||
有时候(比如观察着模式),可以防止循环引用而导致gc无法回收!
|
||||
创建弱引用:wref = weakref.ref(obj)
|
||||
通过弱引用来方位原对象:wref(),如果有则返回原对象,如果已经被删除,则返回None。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> class A:pass
|
||||
...
|
||||
>>> a= A()
|
||||
>>> import weakref
|
||||
>>> ar = weakref.ref(a)
|
||||
>>> print ar
|
||||
<weakref at 0xb76e4694; to 'instance' at 0xb76e3cac>
|
||||
>>> print a
|
||||
<__main__.A instance at 0xb76e3cac>
|
||||
>>> del a
|
||||
>>> print ar
|
||||
<weakref at 0xb76e4694; dead>
|
||||
|
||||
一个例子,这个Cache基本没用,因为在foocache中,使用的是弱引用,每次cache后,都留下一个弱引用,而原始对象马上被销毁,因此实际每次都要计算,cache是废的。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#!/usr/python
|
||||
|
||||
import weakref
|
||||
|
||||
class A:
|
||||
def __init__(self,x):
|
||||
self.val = x
|
||||
|
||||
def __str__(self):
|
||||
return str(self.val)
|
||||
|
||||
def foo(x):
|
||||
print "foo(%s)" % (str(x))
|
||||
return A(x)
|
||||
|
||||
_resultcache = {}
|
||||
def foocache(x):
|
||||
if _resultcache.has_key(x):
|
||||
r = _resultcache[x]()
|
||||
if r is not None:return r
|
||||
r = foo(x)
|
||||
_resultcache[x] = weakref.ref(r)
|
||||
return r
|
||||
|
||||
if __name__ == "__main__":
|
||||
for i in xrange(10):
|
||||
foocache(i)
|
||||
#print foocache(i)
|
||||
|
||||
print "start..."
|
||||
|
||||
for i in xrange(10):
|
||||
#print foocache(i)
|
||||
foocache(i)
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:52:10+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第14章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
本章主要介绍一些和数学计算相关的模块。
|
||||
|
||||
1、decimal模块
|
||||
主要提供浮点运算。Python默认的浮点存储是IEEE 754标准的,对于0.1可能被存储为0.000000000000000001。这类问题在Java等也存在。在一般情况下是可容忍的,但有些时候(比如用于金融行业软件),3 * 0.1 == 0.3会返回False,这是不合适的。
|
||||
dicimal模块采用IBM General Decimal Arthmetic标准。定义了两种个主要类:Decimal和Context类。其中Context是用于控制精度、向上/下取整、出错处理等。
|
||||
|
||||
构造和基本运算:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#构造
|
||||
import decimal
|
||||
x = decimal.Decimal("3.4")
|
||||
y = decimal.Decimal("4.5")
|
||||
|
||||
#基本运算符号都支持
|
||||
>>> x * y
|
||||
Decimal('15.30')
|
||||
|
||||
>>> x / y
|
||||
Decimal('0.7555555555555555555555555556')
|
||||
|
||||
更改精度方法1:
|
||||
每个线程都有一个context对象,直接修改其精确值:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#更改线程的context对象,精度改为3
|
||||
decimal.getcontext().prec = 3
|
||||
c = x * y
|
||||
d = x / y
|
||||
|
||||
#输出
|
||||
>>> x * y
|
||||
Decimal('15.3')
|
||||
>>> x / y
|
||||
Decimal('0.756')
|
||||
|
||||
更改精度方法2:
|
||||
用with块语句,局部改变精度:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#使用with语句块,局部更改精度
|
||||
with decimal.localcontext(decimal.Context(prec=10)):
|
||||
print x * y
|
||||
print x / y
|
||||
|
||||
#输出结果
|
||||
15.30
|
||||
0.7555555556
|
||||
|
||||
2、Decimal对象构造方法:
|
||||
(1)数字
|
||||
d = Decimal(102)
|
||||
(2)字符串
|
||||
d = Decimal(102.3)
|
||||
特殊值:Infinity, -Infinity, Nan(Not a Number)
|
||||
运算函数除了常用的之外:
|
||||
x.exp([context]):自然指数,e ** x
|
||||
x.sqrt([context]):x开根号
|
||||
|
||||
3、Context能控制很多属性,比较重要的是取整和精度。
|
||||
Context(prec=None, rouding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1)
|
||||
prec:精度
|
||||
rouding:取整
|
||||
traps:信号处理机制,当dicimal的对象抛出异常的时候,可以在traps注册函数,以拦截并进行处理。
|
||||
flags:运算状态变量,如是否溢出、被零除等等。
|
||||
capitals:布尔值,幂值是E或者e。
|
||||
|
||||
getcontext()和localcontext():返回当前线程的Context。
|
||||
也可用前面提到的with方法获得:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
with localcontext() as c:
|
||||
c.prec = 5
|
||||
#xxxx statements
|
||||
|
||||
对于0来说,可认为是正号,也可认为是符号。
|
||||
|
||||
4、fractions,小数模块,它存在的意义是:对于无限小数,很多无法精确表示。比如1/3
|
||||
构造方法:
|
||||
(1)从浮点数
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> fractions.Fraction("1.75")
|
||||
Fraction(7, 4)
|
||||
|
||||
(2)从分数,例如1/3:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#会自动约分的!
|
||||
>>> fractions.Fraction(20,100)
|
||||
Fraction(1, 5)
|
||||
|
||||
5、小数的运算和其他运算类似,不再赘述。
|
||||
|
||||
6、math模块,除了我们常用的abs、ceil等,还有一些值得注意的:
|
||||
fsum(seq):全精确的计算求和,因为有时候浮点数之间运算会导致数被省略等。
|
||||
hypot(x,y):计算点的平方的和:sqrt(x*x + y * y)
|
||||
|
||||
7、numbers模块:定义了一系列抽象函数,分别对应基础类型,如Number、Complex、Real、Rational、Integeral。
|
||||
|
||||
8、随机random模块。
|
||||
random.seed([x]):随机化种子,如果省略,则用系统时钟做种子。
|
||||
random.randint(a,b),返回[a,b]之间的随机整数
|
||||
random.choice(seq):从seq的序列中随机选取一个元素。
|
||||
random.sample(seq,len):和楼上类似,不过是指定长度的。这个用于验证码很完美吧!
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#生成4位数字的验证码
|
||||
>>> "".join(random.sample("1234567890",4))
|
||||
'7401'
|
||||
|
||||
random.uniform(a,b):返回随机浮点数,在[a,b)之间。
|
||||
random.random():然会随机浮点数,在[0.0,1.0)之间。
|
||||
|
||||
最后注意一点:随机模块不是线程安全的!!
|
||||
@@ -0,0 +1,66 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:48:17+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第15章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
本章主要介绍抽象类和一些高级的Collection。
|
||||
|
||||
1、abc模块:抽象类模块。
|
||||
一个抽象类的例子:
|
||||
(1)__metaclass__用ABCMeta替换
|
||||
(2)抽象方法用@abstractmethod标注
|
||||
(3)抽象属性用@abstractproperty标注
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
from abc import ABCMeta,abstractmethod,abstractproperty
|
||||
class Stackable:
|
||||
__metaclass__ = ABCMeta
|
||||
@abstractmethod
|
||||
def push(self,item):
|
||||
pass
|
||||
@abstractmethod
|
||||
def pop(self):
|
||||
pass
|
||||
@abstractproperty
|
||||
def size(self):
|
||||
pass
|
||||
|
||||
2、抽象方法和属性必须被子类全部实现后,才能实例化!
|
||||
|
||||
3、array模块:类似list,只不过其中所含元素必须全部相同!
|
||||
array模块的优点是:比list省空间!运算速度更快。缺点是之中类型显然不够灵活!
|
||||
array(typecode)
|
||||
typecode可以取基本类型(主要是char、整形、浮点),具体见书P259页。
|
||||
|
||||
4、bisect模块:在有序队列上插入并保持排序!(基于二分查找)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> lst = [1,2,5,6,7]
|
||||
>>> bisect.insort(lst,4)
|
||||
>>> print lst
|
||||
[1, 2, 4, 5, 6, 7]
|
||||
|
||||
也有其他方法,用于二分查找:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> lst = [1,2,5,6,7]
|
||||
>>> bisect.bisect(lst,4)
|
||||
2
|
||||
|
||||
上面返回2,表示它应该被插入到2的位置!
|
||||
|
||||
5、collections模块:
|
||||
deque:双向队列
|
||||
defaultdict:与dictionary一样,只是对keyerror的处理不同。
|
||||
namedtuple:命名的tuple,与传统tuple兼容,在提供作为参数时非常管用。
|
||||
heapq:优先队列!
|
||||
itertools:用于iter的工具。
|
||||
itertools.chain(itr1,itr2…):把N个itr串联,一个end后执行下一个!
|
||||
itertools.cycle(itr):对itr循环!到了end后回到头。
|
||||
itertools.ifilter(func,iterable):仅当func返回True时,才产生itr。
|
||||
|
||||
完毕。
|
||||
@@ -0,0 +1,446 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:46:50+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第1章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
http://www.coder4.com/archives/1475
|
||||
|
||||
1、Python是解释型语言。
|
||||
|
||||
2、在python解释器下,下划线”_”存储了上次计算的结果。
|
||||
|
||||
3、关于print的写法:print(“Hi!”)是Python2和3的,print “Hi!”是Python2的。
|
||||
|
||||
4、程序退出的方法:*nix(Ctrl+D)、Windows(Ctrl+Z)、程序中(raise SystemExit异常)
|
||||
|
||||
5、每一行算一条语句,如果要一行中表示多条,用分号”;”分割。
|
||||
|
||||
6、Block靠缩进识别(一般为4个空格),没有花括号。
|
||||
|
||||
7、如果Block下暂时没有代码,(如分支的某个if)必须用pass代替,否则格式会报错。
|
||||
|
||||
8、类似printf的print方法:print( “%3d %.2f” % (year,) ),即用百分号“%”分割。
|
||||
|
||||
9、python没有switch,只能用if和elif:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
if suffix == ".htm":
|
||||
content = "text/html"
|
||||
elif suffix == ".jpg":
|
||||
content = "image/jpeg"
|
||||
elif suffix == ".png:
|
||||
centent = "image/png"
|
||||
else:
|
||||
raise RUntimeError("Unknown content type")
|
||||
|
||||
10、in是操作符号,用在sequence(map、list、tuple等)中时,检查seq中是否含有某元素。用在字符串中时,检查是否为子串,返回True或者False。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#检查元素
|
||||
arr = [1,2,3,4,5]
|
||||
if 1 in arr:
|
||||
print "Has 1"
|
||||
else:
|
||||
print "None"
|
||||
#查找字串
|
||||
if "spam" in s:
|
||||
has_spam = True
|
||||
else:
|
||||
has_spam = False
|
||||
|
||||
11、文件读写
|
||||
基础版本代码,性能较低,因为将会把所有数据都读入内存!后面几章会介绍使用yield的版本,不会都调入内存,性能更好。
|
||||
代码1:比较初级
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
f = open("../ExpInfoDAO.cc")
|
||||
line = f.readline()
|
||||
while line:
|
||||
print line, #这里加上,会防止多换一行。
|
||||
line = f.readline()
|
||||
f.close()
|
||||
|
||||
代码2:更简洁,只有两行!
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
for line in open("../ExpInfoDAO.cc"):
|
||||
print line,
|
||||
|
||||
如果想要输出到文件怎么办呢?
|
||||
假设已经打开f = open(“out”,”w”)
|
||||
print >>f,”Hi” #Python2的方法
|
||||
print(“Hi”,file=f) #Python3的方法
|
||||
|
||||
12、字符串string:包含在单、双、三引号中:’Hi’,”Hi”。三引号可多行,多用于doc:
|
||||
“”“
|
||||
I
|
||||
can
|
||||
do
|
||||
it
|
||||
“”"
|
||||
|
||||
13、string也是sequence的一种,但是是不可变的!(immutable,和tuple一样)
|
||||
|
||||
14、字符串可用加号+连接:g = a + “Test string”。
|
||||
可以slice(切分、取字串):
|
||||
a = “Hello world.”
|
||||
b = a[4] # a == “o”
|
||||
b = a[:5] # a==”Hello”
|
||||
类似的,用2~3个下标可非常轻松的取出字串
|
||||
|
||||
15、string->其他:使用int()、float()将字符串强制转化为其他类型:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> x = int("12")
|
||||
>>> x
|
||||
12
|
||||
|
||||
16、其他->string:使用str()、repr()、format()。str一般是直接字符转换(直译)、repr是翻译为内置类型的字符串(译意),format翻译完了再格式化。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> x = 3L
|
||||
>>> str(x)
|
||||
'3'
|
||||
>>> repc(x)
|
||||
>>> repr(x)
|
||||
'3L'
|
||||
>>> format(x,"0.5f")
|
||||
'3.00000'
|
||||
|
||||
17、list是sequence的一种,用方括号表示:[1,2,"3",4,[5,6]]。可以嵌套任意类型。
|
||||
|
||||
18、list的基础操作:slice、加运算、list复合(comprehension)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#slice
|
||||
>>> names = ["Li","He","Yuan"]
|
||||
>>> names[:1]
|
||||
['Li']
|
||||
#加运算
|
||||
>>> names_2 = ["Liu"]
|
||||
>>> names + names_2
|
||||
['Li', 'He', 'Yuan', 'Liu']
|
||||
|
||||
复合运算是比较高级的一种,如下,以打开文件、打印每行为例:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
lines = [line for line in open("../test.txt")]
|
||||
for line in lines:
|
||||
print line,
|
||||
|
||||
上面这个例子这么用有些繁琐,但是做数值计算时候非常有用,经常很有用,比如,求幻方:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> [x*x for x in xrange(1,10)]
|
||||
[1, 4, 9, 16, 25, 36, 49, 64, 81]
|
||||
|
||||
19、Tuples,它和list同属sequence,用圆括号表示,区别是它是不可变的!相对比list更省内存。
|
||||
|
||||
20、Tuples的用途很广泛
|
||||
函数return返回多个值:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#arr = [1,2,3,4,5]
|
||||
def minmax(arr):
|
||||
m1 = min(arr)
|
||||
m2 = max(arr)
|
||||
return (m1,m2)
|
||||
#结果:
|
||||
>>> minmax(arr)
|
||||
(1, 5)
|
||||
|
||||
再比如for时候的unpack解包:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
m = [(1,"liheyuan"),(2,"liuxinrui")]
|
||||
for (name,id) in m:
|
||||
print name," ",id,
|
||||
|
||||
21、set,类似stl和java里的set,非重复无序元素集合,必须用set()函数创建。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#3不会重复的!
|
||||
>>> set([1,2,3,3,4,5])
|
||||
set([1, 2, 3, 4, 5])
|
||||
|
||||
通过add()或者update()都用来添加!前者更新单个元素,后者可写入sequence。
|
||||
s = set("1","2","3")
|
||||
s.add("x")
|
||||
s.update([1,2,3,4])
|
||||
、
|
||||
通过remove()来删除
|
||||
s.remove("x")
|
||||
|
||||
22、Dictionaries(叫法奇怪啊,我更愿意叫map),用花括号写。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
stock = {
|
||||
"name": "GOOG",
|
||||
"shares": 100,
|
||||
"price": 490.10
|
||||
}
|
||||
|
||||
|
||||
要说明的是:任何不可变类型都可做key
|
||||
|
||||
23、Dictionaries的操作:访问value、更新、删除、转化为list。
|
||||
可以直接用下标来完成。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#访问value,直接下标
|
||||
>>> stock["shares"]
|
||||
100
|
||||
|
||||
#更新value,也用下标!
|
||||
>>> stock["shares"] = 200
|
||||
>>> print stock
|
||||
{'price': 490.10000000000002, 'name': 'GOOG', 'shares': 200}
|
||||
|
||||
#删除一个key(和value)
|
||||
>>> del stock["shares"]
|
||||
>>> print stock
|
||||
{'price': 490.10000000000002, 'name': 'GOOG'}
|
||||
|
||||
#转化为list(只转化key)
|
||||
>>> list(stock)
|
||||
['price', 'name']
|
||||
|
||||
|
||||
24、for循环和迭代。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#range一次产生
|
||||
>>> range(10)
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
#xrange是迭代的产生
|
||||
>>> xrange(10)
|
||||
xrange(10)
|
||||
|
||||
#迭代上面的stock
|
||||
>>> for key in stock:
|
||||
... print key,stock[key]
|
||||
...
|
||||
|
||||
price 490.1
|
||||
name GOOG
|
||||
|
||||
|
||||
说明:在Python3中,xrange已经被合并为了range。
|
||||
|
||||
25、函数定义:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
def remainder(a,b):
|
||||
q = a//b
|
||||
r = a - q * b
|
||||
return (q,r)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print remainder(30,7)
|
||||
|
||||
#结果:
|
||||
(4, 2)
|
||||
|
||||
|
||||
26、Generators(生成器、发射器),是一个很有用的功能,可以理解为函数级的”管道“。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
def countdown(n):
|
||||
print "Ready for countdown..."
|
||||
for i xrange(n):
|
||||
yield i
|
||||
|
||||
#用法:获取函数的handle后,依次调用next()来获取下一通过”管道“发射过来的数值。
|
||||
>>> c = countdown(10)
|
||||
>>> c.next()
|
||||
Ready for countdown...
|
||||
0
|
||||
>>> c.next()
|
||||
1
|
||||
>>> c.close()
|
||||
|
||||
|
||||
27、用yield(发射器)来模拟*nix的常用命令:“tail -f log|grep key“
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import os,time
|
||||
def tail(f):
|
||||
f.seek(0,os.SEEK_END)
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
else:
|
||||
yield line
|
||||
|
||||
def grep(lines,key):
|
||||
for line in lines: #注意:必须有是for,不能省略!
|
||||
if key in line:
|
||||
yield line
|
||||
|
||||
if __name__ == "__main__":
|
||||
for line in grep(tail(open("log")),"python"):
|
||||
print line,
|
||||
|
||||
|
||||
28、Coroutines(协同程序)
|
||||
协同程序与发射器有区别,但类似:
|
||||
line = (yied) #用括号( )把yield围起来了。
|
||||
与发射器相反,程序中的协同语句将阻塞,直到send()塞入消息为止。
|
||||
发射器的“生命周期”(工作周期)是从直行第一次开始,到close( )或者函数返回。此外,在第一次send( )之前需要调用一次next( )
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import os
|
||||
import time
|
||||
|
||||
def print_matches(key):
|
||||
print "Looking for,",key
|
||||
while True:
|
||||
line = (yield)
|
||||
if key in line:
|
||||
print line
|
||||
|
||||
def tail(f):
|
||||
f.seek(0,os.SEEK_END)
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
else:
|
||||
yield line
|
||||
|
||||
matchers = [
|
||||
print_matches("python"),
|
||||
print_matches("guido"),
|
||||
print_matches("jython")
|
||||
]
|
||||
|
||||
#在第一次使用一个coroutine之前,必须先调用一次next()函数
|
||||
for m in matchers:
|
||||
m.next()
|
||||
|
||||
wwwlog = tail(open("log"))
|
||||
for line in wwwlog:
|
||||
for m in matchers:
|
||||
m.send(line)
|
||||
|
||||
|
||||
29、查看类(对象)的方法,Python的源代码中含有与javadoc类似的文档机制。
|
||||
使用dir(类名/对象变量名),可以查看某类可用的方法,
|
||||
特殊的方法,是两个下划线开始和结束的,如:__ne__,实际上是重载了操作符!=
|
||||
如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> map = {"a":1,"b":2}
|
||||
>>> dir(map)
|
||||
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
|
||||
|
||||
#__ne__是特殊函数,实际重载了!=操作符
|
||||
>>> map.__ne__({"a":1,"b":2})
|
||||
False
|
||||
>>> map != {"a":1,"b":2}
|
||||
False
|
||||
|
||||
|
||||
这是一个很实用的技巧(我感觉Python的文档没有Javadoc那么详细)。
|
||||
|
||||
30、class里的类函数(相当于c++的static函数)。
|
||||
需要用@staticmethod标记,如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#!/usr/bin/python
|
||||
|
||||
class TestClass:
|
||||
#注意:static函数无需self参数
|
||||
@staticmethod
|
||||
def print_static():
|
||||
print("I'm an static function.")
|
||||
|
||||
def print_non_static(self):
|
||||
print("I'm not an static function.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
TestClass.print_static()
|
||||
tc = TestClass()
|
||||
tc.print_non_static()
|
||||
|
||||
|
||||
31、异常处理方法为:的try、catch:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#!/usr/bin/python
|
||||
|
||||
try:
|
||||
f = open("file.txt","r")
|
||||
except IOError as e:
|
||||
print e
|
||||
finally:
|
||||
print "Finally release other resource."
|
||||
|
||||
|
||||
(2)使用with语句:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
|
||||
|
||||
|
||||
主动抛出异常用raise:
|
||||
raise RuntimeError("Computer says no")
|
||||
|
||||
32、除了finally之外,还可以使用with来自动释放资源:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
with m_lock:
|
||||
message.add(msg)
|
||||
|
||||
|
||||
with操作符由lock重载过了,当进入with时候,会锁住临界区,出with块后会释放锁。
|
||||
|
||||
33、关于简单的doc。
|
||||
在函数下面用三引号定义的,可以用doc函数(或者函数名.__doc__)取出,如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
def TestFunction():
|
||||
"""
|
||||
I'm the doc for TestFunction.
|
||||
"""
|
||||
print("Do nothing.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
TestFunction()
|
||||
|
||||
#可以用__doc__取出。
|
||||
>>> TestFunction.__doc__
|
||||
"\n I'm the doc for TestFunction.\n "
|
||||
|
||||
|
||||
(第一章笔记完)
|
||||
@@ -0,0 +1,80 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:47:36+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第2章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
本章主要是关于字面值和基本的符号。
|
||||
1、一条很长的语句,可以使用空格加斜杠” \”来分割,如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#注意\ 前面又个空格哦!
|
||||
a = 1 + 2 +3 + 4 \
|
||||
+ 5 + 6+ 7
|
||||
|
||||
2、与1相反,当需要多条语句在一行的时候,需要用分号”;”分开。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#注意\ 前面又个空格哦!
|
||||
a = 2;b=3
|
||||
|
||||
3、当某快内没有任何语句的时候,必须用pass占位,因为Pyhon靠缩进来判别代码块,如:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
if a:
|
||||
pass
|
||||
else:
|
||||
print("False !")
|
||||
|
||||
4、标识符:由字母、数字、下划线且非数字开头。和C、C++、Java等基本一样。
|
||||
保留字如下:
|
||||
and del from nonlocal try as elif global not while assert else if or with break except import pass yield class exec in print continue finally is raise def for lambda return
|
||||
|
||||
一个下划线开头的一般有特殊含义。
|
||||
|
||||
5、数字字面值:布尔、整型、浮点、复数。
|
||||
True/False
|
||||
1 111111111111111111L
|
||||
123.45 123e+04
|
||||
1+2j 1-2J
|
||||
|
||||
6、字符串字面值,单引号、双引号、三引号。
|
||||
‘I’m a Word’
|
||||
“Still a Word”
|
||||
“”"
|
||||
I
|
||||
also
|
||||
a
|
||||
word
|
||||
“”"
|
||||
|
||||
7、转移字符:由\开始,与C语言等类似
|
||||
|
||||
8、Python2中默认为byte字符串(ASCII类似),Python3才默认为utf-8,因此经常有乱码的问题。这个非常讨厌,遇到时候再找解决办法吧。
|
||||
|
||||
9、容器(sequence),
|
||||
list:[1,2,3,"Hi"]
|
||||
tuple:(1,2,3,”Hi I cant change”)
|
||||
dictionary:{“a”:1,”b”:2}
|
||||
|
||||
10、(保留的)操作符、特殊符号。
|
||||
很多,不一一列举了。
|
||||
特别注意的是,下述符号也被保留了:# \ @
|
||||
|
||||
11、文档字符串,见上一章,讲过了,在def的下面用三个引号引起来的部分就是。
|
||||
|
||||
12、修饰符,比如上一章的@staticmethod,已经见过了。
|
||||
|
||||
13、源代码的编码
|
||||
如果源代码中出现了其他语言的字符常量,而又与文件编码不一致,可以强制生命编码,文件头写如下内容:
|
||||
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
这样之后,就可以直接使用utf-8的编辑器编辑了。
|
||||
|
||||
(第2章 完毕)
|
||||
|
||||
您可能也喜欢如下文章:
|
||||
@@ -0,0 +1,417 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:50:31+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第3章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
1、Python中,一切都是对象。
|
||||
|
||||
2、类型:type/class,对象/实例:instance。
|
||||
|
||||
3、对象按照是否可以修改,分为可变的 mutable 和不可变的 immutable 。
|
||||
|
||||
4、对象中可以引用其他对象,成为容器 container or collection。
|
||||
|
||||
5、对象有属性(值)和方法(函数)。
|
||||
|
||||
6、Python中的对象无法直接映射到内存空间,但是可以用内置函数id( )函数来查看:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> a = []
|
||||
>>> B = []
|
||||
>>> id(a)
|
||||
3077871564L
|
||||
>>> id(B)
|
||||
3077198956L
|
||||
|
||||
7、操作符is和==的区别:
|
||||
is是比较是否是指向同一个对象(指向的地址是否相同)
|
||||
==是比较指向的值是否相等
|
||||
下面的例子:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
# 初始化
|
||||
>>> a = ["123",456]
|
||||
>>> b = a
|
||||
>>> c = ["123",456]
|
||||
|
||||
# = 比较的是指向的值是否等
|
||||
>>> a == b
|
||||
True
|
||||
>>> a == c
|
||||
True
|
||||
>>> b == c
|
||||
True
|
||||
|
||||
# is比较的是指向地址是否相等
|
||||
>>> a is b
|
||||
True
|
||||
>>> a is c
|
||||
False
|
||||
>>> b is c
|
||||
False
|
||||
|
||||
8、每个对象都有一个类型,用内置函数type查看,可用此比较两个对象是否为同一类型。
|
||||
但是is用于type上,不包含继承类型。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> type([])
|
||||
<type 'list'>
|
||||
>>> a = set()
|
||||
>>> type(a)
|
||||
<type 'set'>
|
||||
#比较
|
||||
type(a) is type(b)
|
||||
|
||||
9、如果需要判断对象类型并考虑继承情况,可以用isinstance。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
# 第一个参数必须是实例,第二个参数必须是类型
|
||||
isinstance(a,list)
|
||||
|
||||
|
||||
10、每个对象都有一个ref-count
|
||||
ref-count加一的情况:赋值给别的对象,加入list等container中。
|
||||
ref-count减一的情况:del删除对象,或者引用的对象出了作用域。
|
||||
使用sys.getrefcount(xx)可以获得xx对象的引用数。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
a = 37
|
||||
print sys.getrefcount(a)
|
||||
b = a
|
||||
c = []
|
||||
c.append(a)
|
||||
print sys.getrefcount(a)
|
||||
del b
|
||||
del c[0]
|
||||
print sys.getrefcount(a)
|
||||
|
||||
#输出结果
|
||||
9
|
||||
11
|
||||
9
|
||||
|
||||
11、加入list、tuple等collection中的是引用!
|
||||
因此如果一个对象被加入两个collection,修改其中一个,另外一个也会被改变。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
a = [1,2]
|
||||
b = [0,a,3]
|
||||
c = [a,55]
|
||||
|
||||
print c
|
||||
b[1][1] = 3
|
||||
print c
|
||||
|
||||
#输出
|
||||
[[1, 2], 55]
|
||||
[[1, 3], 55]
|
||||
|
||||
|
||||
12、如果希望复制给别的引用或者添加到list中的是独立的对象(新的),可以用deepcopy:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import copy
|
||||
a = [1,2]
|
||||
b = copy.deepcopy(a)
|
||||
b[0] = -2
|
||||
|
||||
print a
|
||||
print b
|
||||
|
||||
#输出,经过deepcopy后,就是独立的了。
|
||||
[1, 2]
|
||||
[-2, 2]
|
||||
|
||||
|
||||
13、一个转化数据的例子,我们要把GOOG, 100, 490.10转化为对应的类型:
|
||||
非常精简吧!
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
line = "GOOG, 100 , 490.10"
|
||||
field_types = [str,int,float]
|
||||
fields = [ty(val) for ty,val in zip(field_types,line.split(","))]
|
||||
#结果
|
||||
['GOOG', 100, 490.10000000000002]
|
||||
|
||||
|
||||
14、内置类型:None int long float complex bool str unicode(只有python2有) list tuple xrange dict set frozenset(不可变的set)
|
||||
int值域 -2147483648 ~ 2147483647
|
||||
long值域 无限(取决与内存)
|
||||
float:64bit的浮点标示法。
|
||||
|
||||
15、sequence类型 str unicode list tuple xrange 的共用操作
|
||||
S[i] index
|
||||
S[i:j] slice
|
||||
S[i:j:stride] slice stride是间隔
|
||||
要说明的是,i和j都可以是负数,比如-1表示倒数最后一个。
|
||||
len(S) S中元素的数量
|
||||
min(S) S中最小的
|
||||
max(S) S中最大的
|
||||
sum(S,[初始值]) 累加S
|
||||
all(S) 当S中都为True时返回True,否则False
|
||||
any(S) 当S中有任何一个为True时返回True,否则False
|
||||
|
||||
16、list独有的操作
|
||||
list(s) 转化为list
|
||||
s.append(x) 追加元素到s末尾(如果x是list,则把x整体做为一个元素,追加到s后面)
|
||||
s.extend(t) 追加list到s末尾(如果x是list,则把x打散后,做为N个元素,追加到s后面)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#list.append 整体追加
|
||||
>>> x = [1,2,3]
|
||||
>>> m = [0]
|
||||
>>> m.append(x)
|
||||
>>> print m
|
||||
[0, [1, 2, 3]]
|
||||
|
||||
#list.extend 打散追加
|
||||
>>> x = [1,2,3]
|
||||
>>> m = [0]
|
||||
>>> m.extend(x)
|
||||
>>> print m
|
||||
[0, 1, 2, 3]
|
||||
|
||||
#list.sort 原地排序
|
||||
>>> x = [5,2,5,3,5,4,2]
|
||||
>>> x.sort()
|
||||
>>> x
|
||||
[2, 2, 3, 4, 5, 5, 5]
|
||||
|
||||
|
||||
17、Python 2 中默认是用Byte String而不是Unicode,非常恶心。对字符串的操作不会改变原值!要么返回新的,要么是返回状态。
|
||||
|
||||
str.encode():将unicode的字符串str转化为其他编码,并返回。
|
||||
str.decode():将非unicode编码的字符串str转化为unicode编码的,并返回。
|
||||
encode和decode的参数有时候是可以省略的。
|
||||
|
||||
str.strip(): 移除字符串头和尾部的空白字符,所有空白!包括空格、换行、制表符等等。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#str.capitalize() 返回首字母大写的字符串
|
||||
>>> a = "china"
|
||||
>>> a.capitalize()
|
||||
'China'
|
||||
|
||||
#str.encode() 将unicode的字符串str转化为其他编码,并返回
|
||||
>>> a = u"计算所"
|
||||
>>> b = a.encode("gbk")
|
||||
>>> print b
|
||||
计算所
|
||||
|
||||
#str.decode() 将非unicode编码的字符串str转化为unicode编码的,并返回
|
||||
>>> c = b.decode("gbk")
|
||||
>>> print c
|
||||
计算所
|
||||
|
||||
#str.isupper() 检查str所有字符是否都是大写
|
||||
>>> s = "ABC"
|
||||
>>> s.isupper()
|
||||
True
|
||||
>>> s = "aBC"
|
||||
>>> s.isupper()
|
||||
False
|
||||
|
||||
#str.strip(chrs) 移除字符串头或者尾部的空白(chrs指定)
|
||||
>>> s = " \tchina \r\n"
|
||||
>>> s.strip()
|
||||
'china'
|
||||
|
||||
|
||||
18、xrange,构造i到j的数组,用于循环时候比较多。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#输出
|
||||
>>> for i in xrange(10,20):
|
||||
... print i
|
||||
...
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
|
||||
|
||||
19、map在Python中又叫做Dictionary(词典)。和数组类似,k和v可以使任意数值(k必须是不可变类型)。
|
||||
【常用操作】
|
||||
k in m:检查key是否在map m中。
|
||||
m[k]=v: 对m的key赋值v
|
||||
print m[k]: 访问m的key值k
|
||||
m.has_key(k): m中是否有key k
|
||||
m.setdefault(k,v): 如果m中已经有k,忽略,否则,新建k并设置数值为v
|
||||
|
||||
len(m):map含k-v对儿的个数
|
||||
m.items():遍历所有k和v
|
||||
m.keys():遍历所有k
|
||||
m.values():遍历所有v
|
||||
|
||||
m.copy():影子拷贝,非深度拷贝!
|
||||
|
||||
20、set类型。set是集合,内含元素非重复,可以看作是退化的无value的map。
|
||||
frozenset是不可变的set。
|
||||
|
||||
set和fronzenset的常用操作:
|
||||
set_a.copy()
|
||||
set_a.intersection(another_set):与set取交集。
|
||||
set_a.union(another_set):与set取并集。
|
||||
|
||||
set独有的常用操作(修改的):
|
||||
set_b.add(item)
|
||||
set_b.clear():清空
|
||||
set_b.discard(item):如果item再set_b中,移除,不在的话,无效,不报异常。
|
||||
set_b.remove(item):和discard类似,不过item不在要抛出异常!
|
||||
|
||||
21、lamada函数,其实就是类似Java的匿名类。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
bar = lamada x,y: x + y
|
||||
|
||||
|
||||
Cop Six 's Blog
|
||||
|
||||
22、函数有三种:直接函数、类函数和静态函数:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#直接函数
|
||||
def fun1(x,y):
|
||||
return x+y
|
||||
|
||||
#类函数和静态函数
|
||||
class Foo(object):
|
||||
#类函数,第一个参数必须是self
|
||||
@classmethod
|
||||
def method1(self,arg):
|
||||
pass
|
||||
|
||||
#静态函数,其实就是class的static函数,第一个参数不用是self
|
||||
@staticmethod
|
||||
def method2(arg):
|
||||
pass
|
||||
|
||||
|
||||
23、几个内置对象:
|
||||
Trackback:调用Trackback,一般异常的时候用
|
||||
Generator:构造器
|
||||
Slice:这个不用说了吧,lst[1:2],这种slice的时候就是用的这个对象
|
||||
Ellipsis:下标相应的对象。
|
||||
|
||||
24、特殊函数一般是双下划线开头,如:__add__()是重载的+操作符。再如__getitem__()是重载的[]操作符。
|
||||
|
||||
25、与构造对象相关的特殊函数:
|
||||
__new__():新建对象时。
|
||||
__init__():初始化时。
|
||||
__de__():del xx,操作符。
|
||||
|
||||
new和init一般是同时使用,等价关系是:新建对象=new + init
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#x = A()翻译为:
|
||||
x = A.__new__(A,args)
|
||||
is isinstance(x,A): x.__init__(args)
|
||||
|
||||
|
||||
26、字符串相关的特殊函数:
|
||||
__str__():重载的str(xx)函数。
|
||||
__repr():重载的repr(xx)函数。
|
||||
|
||||
27、特殊函数:
|
||||
__bool__():返回True或者False,用于分支判断时。
|
||||
__len__():重载len()函数。
|
||||
__hash__():返回一个int类型的hash值。
|
||||
|
||||
__lt__(self,other):重载self
|
||||
__ge__(self,other):重载self>=other
|
||||
|
||||
28、属性访问相关的特殊函数
|
||||
__getattr__(self, name):访问属性,x.name
|
||||
__setattr__(self,name):设置属性,x.name=yy
|
||||
__delattr__(self, name):删除属性,del x.name
|
||||
|
||||
29、有时候,我们希望在访问x.name时,加一层逻辑(如log日志),此时可以用Descriptors。
|
||||
|
||||
30、
|
||||
__len__(self):len(item)重载
|
||||
__geitem__(self,key):item[key]重载
|
||||
__contains__(self,obj):返回self中是否含obj,重载了 x in item。
|
||||
|
||||
31、数学操作符特殊函数
|
||||
|
||||
__add__(self,other): self + other
|
||||
__sub__(self,other): self - other
|
||||
__mul__(self,other): self * other
|
||||
__div__(self,other): self / other (Python 2 only)
|
||||
__truediv__(self,other) : self / other (Python 3)
|
||||
__floordiv__(self,other): self // other
|
||||
__mod__(self,other): self % other
|
||||
__divmod__(self,other): divmod(self,other)
|
||||
__pow__(self,other [,modulo]) : self ** other, pow(self, other,modulo)
|
||||
__lshift__(self,other): self << other
|
||||
__rshift__(self,other) : self >> other
|
||||
__and__(self,other) : self & other
|
||||
__or__(self,other): self | other
|
||||
__xor__(self,other): self ^ other
|
||||
__radd__(self,other) : other + self
|
||||
__rsub__(self,other) : other - self
|
||||
__rmul__(self,other): other * self
|
||||
__rdiv__(self,other) : other / self (Python 2 only)
|
||||
__rtruediv__(self,other) : other / self (Python 3)
|
||||
__rfloordiv__(self,other) : other // self
|
||||
__rmod__(self,other): other % self
|
||||
__rdivmod__(self,other) : divmod(other,self)
|
||||
__rpow__(self,other) : other ** self
|
||||
__rlshift__(self,other) : other << self
|
||||
__rrshift__(self,other): other >> self
|
||||
__rand__(self,other) : other & self
|
||||
__ror__(self,other): other | self
|
||||
__rxor__(self,other): other ^ self
|
||||
__iadd__(self,other) : self += other
|
||||
__isub__(self,other) : self -= other
|
||||
__imul__(self,other) : self *= other
|
||||
__idiv__(self,other) : self /= other (Python 2 only)
|
||||
__itruediv__(self,other) : self /= other (Python 3)
|
||||
__ifloordiv__(self,other): self //= other
|
||||
__imod__(self,other) : self %= other
|
||||
__ipow__(self,other): self **= other
|
||||
__iand__(self,other) : self &= other
|
||||
__ior__(self,other) : self |= other
|
||||
__ixor__(self,other) : self ^= other
|
||||
__ilshift__(self,other): self <<= other
|
||||
__irshift__(self,other): self >>= other
|
||||
__neg__(self): –self
|
||||
__pos__(self): +self
|
||||
__abs__(self) : abs(self)
|
||||
__invert__(self): ~self
|
||||
__int__(self): int(self)
|
||||
__long__(self): long(self) (Python 2 only)
|
||||
__float__(self) : float(self)
|
||||
__complex__(self) : complex(self)
|
||||
|
||||
32、with操作符。
|
||||
with context [ as var]:
|
||||
statements
|
||||
重载函数为__enter__(self)和__exit__(self, type, value, tb)
|
||||
|
||||
33、dir函数,辅助函数,类似help
|
||||
__dir__(self):重载了dir函数。
|
||||
|
||||
第三章完毕。
|
||||
@@ -0,0 +1,162 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:51:06+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第4章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
1、关于除法/和//。
|
||||
在Python 2中,/还是整除,即只返回整数部分。
|
||||
而Python 3中,/变为浮点除,不在约为整数。
|
||||
|
||||
在Python 2中,想要获取浮点结果,可以将除数或者被除数强转为float:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
float(1)/100
|
||||
0.01
|
||||
|
||||
2、一些有用的函数
|
||||
abs(x):返回x的绝对值
|
||||
pow(x,y):x ^ y,等价于x ** y
|
||||
round(x):返回离x最近的10^n值,n可正或者负
|
||||
|
||||
3、关于对tuple、list、字符等的乘法:重复字符
|
||||
如’a’ * 5或者 5 * ‘a’都行:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> 'a' * 10
|
||||
'aaaaaaaaaa'
|
||||
>>> 10 * 'a'
|
||||
'aaaaaaaaaa'
|
||||
|
||||
4、
|
||||
all(s):s中所有元素都是true时,返回true。
|
||||
any(s):s中有任何元素为true时,返回true。
|
||||
|
||||
5、v1, v2…, vn = S,将S容器unpack给v1~vn
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#字符串也可以unpack
|
||||
>>> x,y,z = "abc"
|
||||
>>> print x,y,z
|
||||
a b c
|
||||
|
||||
但是注意,unpack出的v和S里面的格式必须完全一致!
|
||||
|
||||
6、s[-1]:倒数第一个元素。
|
||||
s[i:j],是取所有的k,其中i<=k< p=""> <>
|
||||
|
||||
7、对于字符串,in和not in可以相当于子字符串查找,但是它不支持正则表达式!
|
||||
|
||||
8、s[ i:j ] = r,将s[i,j)都替换为r。
|
||||
|
||||
9、del s[i]的时候,出了从list移除之外,还会删除引用计数!
|
||||
|
||||
10、sequence之间也可以比,< > <= >= == 和!=。单都是基于全部匹配的。
|
||||
|
||||
11、字符串通过字典序比较。
|
||||
|
||||
12、不要将Unicode和普通Byte String混合使用。
|
||||
|
||||
13、String格式化(s % d),d是tuple,s是格式化的字符串。
|
||||
|
||||
14、String格式化时,d也可以不是tuple而是dictionary,如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> stock = { "name":"GOOG","shares":100,"price":300 }
|
||||
>>> "%(shares)d of %(name)s at %(price)0.2f" % stock
|
||||
#格式化后结果
|
||||
'100 of GOOG at 300.00'
|
||||
|
||||
15、更高级的字符串格式化,format(*args,*kwargs),这之中交叉使用了顺序参数和key-value参数。
|
||||
|
||||
这些高级字符串格式化方法都使用format,并且用{ }
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> r = "{0} {1} {2}".format("GOOG",100,500.1)
|
||||
>>> print r
|
||||
#输出
|
||||
GOOG 100 500.1
|
||||
|
||||
#混合使用,加入key-value取值
|
||||
>>> "{name:8} {share:8d} {price:8.2f}".format(name="lhy",share=100,price=500.1)
|
||||
'lhy 100 500.10'
|
||||
|
||||
16、Dictionary上的一些操作:
|
||||
|
||||
x = d[k]:取dict d中的key k
|
||||
d[k] = x:设置dict d中的k对应val为x
|
||||
del d[k]:删除d中key为k的
|
||||
k in d:如果d中有以k为键的元素,返回True,否则False
|
||||
len(d):dict中的长度
|
||||
|
||||
17、set和frozenset都支持并| 交& 差- 反^,len,max,min等操作
|
||||
|
||||
18、对字符串使用+=,相当于拼接字符串的简写。
|
||||
|
||||
19、对点.的使用:为属性访问操作符。
|
||||
如foo.x = 3
|
||||
在一行中可连用多个点.,如foo.bar(3,4,5).spam
|
||||
|
||||
20、使用functools包的partial函数可以分两次来给函数传入参数:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> def func(x,y,z):
|
||||
... return x + y + z
|
||||
...
|
||||
>>> f = partial(func,1,2)
|
||||
>>> from functools import partial
|
||||
>>> f = partial(func,1,2)
|
||||
>>> f(3)
|
||||
6
|
||||
|
||||
21、Python中类型之间的转换没有C、C++那么麻烦,直接类型名()的函数即可。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> a = "123"
|
||||
>>> b = int(a)
|
||||
>>> print b
|
||||
123
|
||||
|
||||
|
||||
22、unichar:将整型转化成对应的unicode的char
|
||||
chr:将int转化成对应的ascii码的char
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#chr转化为ascii码的字符
|
||||
>>> a = 49
|
||||
>>> chr(a)
|
||||
'1'
|
||||
|
||||
#unichar转为unicode的字符
|
||||
>>> a = 21271 #21271是北的unicode编码
|
||||
>>> print unichr(a)
|
||||
北
|
||||
|
||||
|
||||
23、在用于分支判断等时,Ture/False和其他类型的转换:所有非零的数、非空字符串、list、tuple、dictionary都会被视为True。而False,0,None空list、tuple等转化为False。
|
||||
|
||||
24、x == y,检查两个对象在逻辑上是否相等(如完全相同的字典序、容器中每个元素都相同等)
|
||||
而
|
||||
x is y,则检查两个对象是否指向同一个引用(即指向的内存地址是否相同)。
|
||||
|
||||
25、乘幂运算 ** 是右结合。
|
||||
|
||||
26、Python中没有C、C++、就Java等之中常见的三元操作符,但是可以用一行写if:
|
||||
minvalue = a if a<=b else b
|
||||
类似的,也可以用于[构造数组]中:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
[x if x < 50 else 50 for x in values]
|
||||
|
||||
|
||||
完毕。
|
||||
@@ -0,0 +1,289 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:48:39+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第7章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
1、类(class)和实例(instances)是1对N的关系。
|
||||
|
||||
2、class由若干函数、变量(类成员)、属性(实例成员)组成。
|
||||
一个示例的类如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class Account(object):
|
||||
|
||||
num_account = 0 #类成员,所有示例共享!
|
||||
|
||||
def __init__(self,name,balance): #构造函数
|
||||
self.name = name #实例成员
|
||||
self.balance = balance #实例成员
|
||||
Account.num_account += 1 #更新类成员
|
||||
|
||||
def withdraw(self,amt): #注意一定要有self
|
||||
self.balance -= amt #更新实例成员
|
||||
|
||||
3、类的实例化
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#实例化,会调用__init__函数
|
||||
a = Account("He",1000)
|
||||
b = Account("Rui",2000)
|
||||
|
||||
#操作 ( attribute binding ),会先检查有无该属性或者函数,注意无self参数,显然的。。
|
||||
a.withdraw(100)
|
||||
|
||||
4、Python无类作用域,即对实例(无论是函数还是属性)的操作都必须加self完成。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class Foo(object):
|
||||
|
||||
def bar(self):
|
||||
print("bar!")
|
||||
|
||||
def spam(self):
|
||||
bar(self) #错误!
|
||||
self.bar() #正确!
|
||||
|
||||
5、python中的继承:基类( base class )、派生类 ( derived class ),派生类继承基类的所有属性和方法,并可以选择重写或移除。object是所有Python对象的基类(和Java的Object一样)。一个继承类的写法很简单,就是在def时class B(A):,A为基类,B为派生类。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class EvilAccount(Account):
|
||||
|
||||
def badwithdraw(self,amt):
|
||||
self.balance -= 2 * amt
|
||||
|
||||
而调用是,依然是
|
||||
c = EvilAccount(“Me”,1500) #继承了基类的__init__方法
|
||||
c.badwithdraw(1000) #直接定位到派生类
|
||||
c.withdraw(1000) #派生类没有,定位到基类
|
||||
|
||||
6、派生类调用基类构造函数:多数发生在派生类的构造函数与基类参数不同时。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class EvilAccount(Account):
|
||||
|
||||
def __init__(name,balance,factor): #派生类与基类的构造函数不同
|
||||
Account.__init__(name,balance) #派生类调用基类的构造函数
|
||||
self.f = factor #然后初始化自己的特有成员变量
|
||||
|
||||
7、派生类如何调用父类的函数:
|
||||
(1)self.xxx(abcd)
|
||||
(2)super(cls, instance).xxx(abcd)
|
||||
例如:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class MoreEvilAccount(EvilAccount):
|
||||
def deposit(self, amount):
|
||||
self.withdraw(5.00)
|
||||
super(MoreEvilAccount,self).desposit(amount) #调用父类的desposit方法
|
||||
|
||||
8、Python支持多继承,但属性间的冲突会导致很多问题,所以不建议使用。
|
||||
|
||||
9、多态/Duck Typing:Python一直都是运行时决定类型,因此有人称之为Duck Typing,即“鸭式类型”。好处是,可以定义一些内部方法、属性很类似但又无继承关系的类。例如标准库中的file-like文件。
|
||||
|
||||
10、静态方法和类方法。
|
||||
可以说,类方法是静态方法的一个拓展吧(不再局限于类了)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class Foo(object):
|
||||
|
||||
factor = 1
|
||||
|
||||
@staticmethod
|
||||
def add(x,y):
|
||||
return x+y
|
||||
|
||||
@classmethod
|
||||
def mul(cls,s):
|
||||
return cls.factor*x
|
||||
|
||||
标准的调用方法都一样:
|
||||
Foo.add(3,4)
|
||||
Foo.mul(4,5)
|
||||
除此之外,python并没有限定类方法和静态方法不能用于实例上,因此如下也是合法的:
|
||||
f = Foo()
|
||||
f.add(3,4)
|
||||
f.mul(5,6)
|
||||
|
||||
11、属性标记@property,标记后,可以向访问实例属性一样自动get,如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#给函数加@property属性
|
||||
class Cicle(object):
|
||||
def __init__(self,radius):
|
||||
self.radius = radius
|
||||
@property
|
||||
def area(self):
|
||||
return math.pi * self.radius *2
|
||||
|
||||
#调用时可视作属性一样get
|
||||
>>> c = Circle(4.0)
|
||||
>>> c.radius
|
||||
>>> 4.0
|
||||
|
||||
如果不加上述@property,则返回值c.radius会被视为是函数area的实例。
|
||||
m = c.radius #m是函数实例
|
||||
真正的m()时,才会调用c.radius()
|
||||
|
||||
12、一般来说,最好用getter和setter对实例内的属性进行保护,上面的@property只是getter方法,如何实现让函数类似的属性可以被赋值呢?需要@xxx.setter和@xxx.deleter。如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class Cicle(object):
|
||||
|
||||
def __init__(self,area):
|
||||
self.__area__ = area
|
||||
@property
|
||||
def area(self):
|
||||
return self.__area__
|
||||
|
||||
@area.setter
|
||||
def area(self,value):
|
||||
self.__area__ = value
|
||||
|
||||
@area.deleter
|
||||
def area(self):
|
||||
raise TypeError("can't delete name.")
|
||||
|
||||
|
||||
标签@area.deleter的.前面的area必须完全匹配@property标记的属性!
|
||||
这样后,就可以如下用啦!
|
||||
c = Cicle()
|
||||
a = c.area
|
||||
c.area = 123.2
|
||||
del c.area
|
||||
|
||||
13、也可以用用户自定义的get和set方法来做隔离。它们是:__get__()、__set__()、__delete__()函数。
|
||||
|
||||
14、关于私有函数/变量。根据Python约定,以下划线_开头的,可视为私有变量,但无明确语法限制。
|
||||
|
||||
15、对象的内存管理:创建对象时,会调用class的__new__()和__init__()。
|
||||
__new__()的用法一般很罕见,主要用途为:
|
||||
(1)从一些不可变类继承时,在new中更改一些数值,入string,tuple等。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class UpperStr(str):
|
||||
def __new__(cls,value=""):
|
||||
return str.__new__(cls,value.upper())
|
||||
|
||||
u = UpperStr("hello") #value is "HELLO"
|
||||
|
||||
|
||||
(2)__new__()用于metaclass,后面会讲到
|
||||
|
||||
16、对象的管理也是基于引用计数:reference counting。当rc降到0的时候,会删除对象,此时调用自定义的__del__()如果有的话。__del__()一般也无需定义,除非你要显示的关闭文件、关闭网络socket、释放链接等操作。一般这些都不应该在__del__()中完成,和Java的finalize()道理一样。
|
||||
|
||||
17、引用计数rc并非完美,又是会产生‘“环引用”,导致内存泄漏,典型的就是“观察者模型”,此时可用弱引用解决问题。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import weakref
|
||||
class AccountObserver(object):
|
||||
def __init__(self, theaccount):
|
||||
self.accountref = weakref.ref(theaccount ) #create weakref
|
||||
|
||||
|
||||
18、默认情况下,python的属性名集合是用dirtionary(类似map)的结构实现的,记录在cls.__dict__中。
|
||||
当实例的任何属性self.xxx变化时,都会反应到cls.__dict__中。访问属性时,最终会调用内置的__getattr__()、__setattr__()和__delattr__(),如果需要,可以在这三个地方做拦截器(记录日志之类的)。
|
||||
|
||||
19、可以替换属性集合的内置数据结构,采用__slot__,它将限定属性可使用的名称,换来更小的内存和更快的运行时间。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import weakref
|
||||
class AccountObserver(object):
|
||||
__slot__ = ('name', 'balance')
|
||||
.... #属性只能命名为name和balance
|
||||
|
||||
|
||||
由于不使用__dict__,对属性的访问也不会在进入__getattr__()等函数了。
|
||||
此外,在继承的时候,子类必须也定义__slot__,否则内存消耗会更大!因此继承时候要谨慎使用。
|
||||
|
||||
20、python支持重载操作符,例如对加号+的重载如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class Complex:
|
||||
|
||||
def __init__(self,real,imag=0):
|
||||
self.real = float(real)
|
||||
self.imag = float(imag)
|
||||
|
||||
def __repr__(self):
|
||||
return "Complex(%s,%s)" % (self.real,self.imag)
|
||||
|
||||
def __str__(self):
|
||||
return "(%g+%gj)" % (self.real,self.imag)
|
||||
|
||||
def __add__(self,other):
|
||||
return Complex(self.real + other.real, self.imag + self.imag)
|
||||
|
||||
def __sub__(self,other):
|
||||
return Complex(self.real - other.real, self.imag - self.imag)
|
||||
|
||||
|
||||
21、检查一个实例是否属于某一类:isinstance(obj,name)
|
||||
issubclass(A,B):如果类A属于类B,注意A和B都是cls,不是实例。
|
||||
isinstance和issubclass都是可以重写的,这点上python比较灵活。
|
||||
|
||||
22、抽象类:Python支持抽象类,需要引用abc模块。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||
|
||||
class Foo:
|
||||
__meta__ = ABCMeta #must 1
|
||||
|
||||
@abstractmethod #must 2
|
||||
def spam(self,a,b):
|
||||
pass
|
||||
|
||||
@abstractproperty #must 2
|
||||
def name(self):
|
||||
pass
|
||||
|
||||
|
||||
抽象类肯定是不能直接被实例化的,实现抽象类得方法并不是继承!而是注册,如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
class Grok:
|
||||
def spam(self,a,b):
|
||||
print("Grok.spam")
|
||||
|
||||
Foo.register(Grok)
|
||||
|
||||
|
||||
23、Metaclass,我没看懂 - - 感觉是类似于Java的反射代理机制,用于框架时候比较给力。
|
||||
|
||||
24、类包装器Class Decorators: take a class as input and returns a class as output
|
||||
其实也没太明白用途。。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#类包装器
|
||||
registry = { }
|
||||
def register(cls):
|
||||
registry[cls.__clsid__] = cls
|
||||
return cls
|
||||
|
||||
@register
|
||||
class Foo(object):
|
||||
__clsid__ = "123-456"
|
||||
def bar(self):
|
||||
pass
|
||||
|
||||
#用法
|
||||
register(Foo)
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:49:04+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第8章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
1、Python程序可以通过模块(modules)和包(package)来组织,简单来说,模块就是xx.py文件,而包就是一组这种文件组成的文件夹(含子文件夹)
|
||||
|
||||
2、如1中所属,每一个.py文件都可以看做是一个模块,通过import来引用。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#spam.py
|
||||
a = 37
|
||||
def foo():
|
||||
print("I'm foo and a is %d" % a)
|
||||
|
||||
def bar():
|
||||
print("I'm bar and calling to foo")
|
||||
|
||||
class Spam(object):
|
||||
def grok(self):
|
||||
print("I'm Spam.grok in moudles spam")
|
||||
|
||||
#调用
|
||||
import spam
|
||||
x = spam.a
|
||||
spam.foo()
|
||||
......
|
||||
|
||||
3、import时会执行模块中的所有语句,包括你可能的一些测试语句。当然他们只会被执行一遍(不管被import了多少次)
|
||||
|
||||
4、import仅仅是表示当前程序知道了那个模块的命名空间,使用的时候,必须带上模块,比如上面的例子:
|
||||
obj = spam.Spam()
|
||||
|
||||
5、可以通过逗号,来引用多个模块:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import socket, os, re
|
||||
|
||||
|
||||
6、可以对import进来的模块重命名,这在解决重名冲突时候非常有用:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import spam as sp
|
||||
|
||||
|
||||
或者,可以作为一种“选择载入”的方法:
|
||||
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
if format == "xml":
|
||||
import xmlreader as reader
|
||||
elif format == "cvs":
|
||||
improt csvreader as reader
|
||||
|
||||
确实挺好用的吧!
|
||||
|
||||
7、模块是Python中的一等公民,也就是说模块可以被赋值到任何变量、列表等等之中……
|
||||
|
||||
8、import可以出现在程序的任意地方,但是不管你写了多少个improt,他会且只会被载入一次。
|
||||
|
||||
9、想知道当前import了那些模块:print sys.modules()
|
||||
|
||||
10、import模块的时候,只是引入了新模块的命名空间。类似于using namespace。但是很多时候,我们需要的是using std::endl这样的,只引用模块中的某函数或者类,这就需要用from functionxxx import modulesxxx。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
from spam import foo
|
||||
foo() #这样就可以直接用foo了!类似于直接cout.....而不用std::cout...
|
||||
|
||||
|
||||
11、from xxx import xxx也是可以用as的!
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
from spam import Spam as Sp
|
||||
s = Sp()
|
||||
|
||||
|
||||
12、from xxxModules import *,可以使用*。这个*并不是全部,而是需要到xxxModules.py里面查找__all__定义。
|
||||
因此是可以隐藏的,例如下面:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#spam.py
|
||||
|
||||
import sys
|
||||
|
||||
__all__ = ['bar','Spam']
|
||||
|
||||
a = 37
|
||||
def foo():
|
||||
print("I'm foo and a is %d" % a)
|
||||
|
||||
def bar():
|
||||
print("I'm bar and calling to foo")
|
||||
|
||||
class Spam(object):
|
||||
def grok(self):
|
||||
print("I'm Spam.grok in moudles spam")
|
||||
|
||||
#print sys.modules
|
||||
|
||||
#此时from spam import *时,就不会有foo()
|
||||
|
||||
|
||||
13、如果模块中使用了global命名空间,则只以定义模块的文件为依据,而非调用的模块!
|
||||
|
||||
14、如何以“main”类似的方式启动模块。
|
||||
如果运行代码(非函数什么的)直接写在模块尾部,则import时候会被全执行,因此可以用下面的方法:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
if __name__ == "__main__":
|
||||
print "Hi, I'm in main"
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
只有单独执行python xxx.py的时候,才会进入"Hi I'm main"这里
|
||||
|
||||
15、模块的搜索。
|
||||
路径在sys.path下,按顺序来,也可以动态添加!
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> print sys.path
|
||||
['D:/python', 'D:\\python', 'C:\\Python27\\Lib\\idlelib', 'D:\\python\\%PYTHONPATH%', 'd:\\python', 'C:\\Windows\\system32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\site-packages']
|
||||
>>>
|
||||
|
||||
# 动态添加
|
||||
sys.path.append("/tmp/xxx")
|
||||
|
||||
|
||||
python会识别的拓展名为:.py .pyw .pyc .pyo以及动态连库
|
||||
|
||||
16、如果是动态连库.pyd,则会同时载入**.so(或者dll)
|
||||
|
||||
17、.py在第一次被import的时候,会被变异为字节码.pyc,优化后的未.pyo。
|
||||
|
||||
18、python搜索模块时候是大小写敏感的!
|
||||
|
||||
19、关于重载入:Python现在的版本中已经无法实现!所以不要尝试动态冲载入(更新.py后想载入新版本的)
|
||||
|
||||
20、包Package,每个包的下面要包含__init__.py。包的子目录下面也要有__init__.py。
|
||||
类似的,也是from xxx improt *的时候,会检查__init__.py的__all__变量。有的才会被import
|
||||
|
||||
21、发布python程序。
|
||||
首先放在一个目录下,加入README等,然后加入如下的setup.py:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name = "spam",
|
||||
version = "1.0",
|
||||
py_modules = ['libspam'],
|
||||
packages = ['spampkg'],
|
||||
scripts = ['runspam.py'])
|
||||
|
||||
|
||||
python setup.py sdist #自动打包生成一个zip。
|
||||
python setup.py install #安装到本地(通常是用户下载会zip包后解压缩后执行)
|
||||
python setup.py bdist #生成一个二进制版本(都编译成pyc了)
|
||||
其他可转化成可执行程序的工具:py2exe(windows), py2app(MAC OS),可怜的linux下还没有
|
||||
|
||||
22、也可以用setuptools,则setup.py修改为:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
try:
|
||||
from setuptools import setup
|
||||
except ImportError:
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name = "spam",
|
||||
version = "1.0",
|
||||
py_modules = ['libspam'],
|
||||
packages = ['spampkg'],
|
||||
scripts = ['runspam.py'])
|
||||
|
||||
|
||||
23、Python的包都可以从PyPI上下载。http://pypi.python.org。
|
||||
python setup.py install #安装
|
||||
python setup.py install --user #安装到用户的目录下(home相关)
|
||||
python setup.py install --prefix #安装到其他目录,一般需要修改sys.path。
|
||||
很多插件都用了c/c++,则需要对应编译器。
|
||||
|
||||
24、使用easy_install可以从网上直接下载,然后安装。
|
||||
|
||||
25、附上setuptools(含easy_install)的安装方法:
|
||||
Linux下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
wget -q http://peak.telecommunity.com/dist/ez_setup.py
|
||||
sudo python ./ez_setup.py
|
||||
|
||||
|
||||
Windows下,下载并安装:http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11.win32-py2.7.exe#md5=57e1e64f6b7c7f1d2eddfc9746bbaf20
|
||||
@@ -0,0 +1,241 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-07-05T14:49:26+08:00
|
||||
|
||||
====== Python Essential Reference 4th – 第9章 – 读书笔记 ======
|
||||
Created 星期二 05 七月 2011
|
||||
|
||||
本章主要是关于各种I/O操作,包括File-Objec及其操作、Unicode字符串相关的I/O函数以及对象的序列化和持久化。
|
||||
|
||||
1、从cmd读取传入参数:sys.argv。其中sys.argv[0]是当前的程序名称。
|
||||
|
||||
2、想要退出系统时,出了exit和return外,还可以raise SystemExit(1)
|
||||
|
||||
3、解析命令行参数,可以使用optparse模块。
|
||||
不过从2.7之后,Python将废弃optparse,转而支持argparse,话说开源的东西变动太大。。。
|
||||
optparse的用法如下:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import optparse
|
||||
|
||||
p = optparse.OptionParser()
|
||||
|
||||
#Add option of -o/--output
|
||||
p.add_option("-o",action="store",dest="outfile")
|
||||
p.add_option("--output",action="store",dest="outfile")
|
||||
|
||||
#Add option of boolean
|
||||
p.add_option("-d",action="store_true",dest="debug")
|
||||
p.add_option("--debug",action="store_true",dest="debug")
|
||||
|
||||
#Set default values
|
||||
#p.set_default(debug=False)
|
||||
|
||||
opts,args = p.parse_args()
|
||||
|
||||
print opts.outfile,opts.debug
|
||||
|
||||
4、环境变量:os.envviron
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
>>> import os
|
||||
>>> print os.environ
|
||||
{'TMP': 'C:\\Users\\liheyuan\\AppData\\Local\\Temp', 'COMPUTERNAME': 'LIHEYUAN-PC', 'USERDOMAIN': 'liheyuan-PC', 'PSMODULEPATH': 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'PROCESSOR_IDENTIFIER': 'x86 Family 6 Model 23 Stepping 10, GenuineIntel', 'PROGRAMFILES': 'C:\\Program Files', 'PROCESSOR_REVISION': '170a', 'SYSTEMROOT': 'C:\\Windows', 'HOME': 'C:\\Users\\liheyuan', 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'TK_LIBRARY': 'C:\\Python27\\tcl\\tk8.5', 'TEMP': 'C:\\Users\\liheyuan\\AppData\\Local\\Temp', 'PROCESSOR_ARCHITECTURE': 'x86', 'TIX_LIBRARY': 'C:\\Python27\\tcl\\tix8.4.3', 'ALLUSERSPROFILE': 'C:\\ProgramData', 'SESSIONNAME': 'Console', 'HOMEPATH': '\\Users\\liheyuan', 'USERNAME': 'liheyuan', 'LOGONSERVER': '\\\\LIHEYUAN-PC', 'LOCALAPPDATA': 'C:\\Users\\liheyuan\\AppData\\Local', 'PROGRAMDATA': 'C:\\ProgramData', 'PYTHONPATH': '%PYTHONPATH%;d:\\python;d:\\python;d:\\python', 'TCL_LIBRARY': 'C:\\Python27\\tcl\\tcl8.5', 'PATH': 'C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\Common Files\\Thunder Network\\KanKan\\Codecs', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'FP_NO_HOST_CHECK': 'NO', 'WINDIR': 'C:\\Windows', 'APPDATA': 'C:\\Users\\liheyuan\\AppData\\Roaming', 'HOMEDRIVE': 'C:', 'SYSTEMDRIVE': 'C:', 'NUMBER_OF_PROCESSORS': '2', 'PROCESSOR_LEVEL': '6', 'OS': 'Windows_NT', 'PUBLIC': 'C:\\Users\\Public', 'USERPROFILE': 'C:\\Users\\liheyuan'}
|
||||
|
||||
5、File-Object。
|
||||
内置的open方法:open(name,mode,bufsize),后两个参数是可选的。
|
||||
|
||||
mode可取r(读)、w(写)或a(追加)。默认情况下,为了解决windows和linux下对换行的差异(windows下是\r\n,linux是\n),默认会对其进行转换统一成\n,这个转换可以通过rU关闭,或者U启用。如果要用二进制模式b,则不会进行自动换行转换。如果需要及时更新,则在r或者w或者a后面加上+。
|
||||
|
||||
bufsize是读取、写入的缓存,0为关闭,1是行缓存,>1之后是用字节表示的读取次数。
|
||||
|
||||
File-Object的操作很多,比较特别需要注意的如下:
|
||||
f.readline([n]),读取一行,接近n个字节时停止,n省略时就是一行。
|
||||
f.readlines([size]),读取所有的行,以list形式返回,可选接近size个字节时停止。
|
||||
f.close(),关闭释放资源。
|
||||
f.tell(),定位当前偏移量。
|
||||
f.seek(),随机访问文件的某一位置。
|
||||
|
||||
6、File读取完毕后,会返回None,而非抛出异常!
|
||||
因此逐行读取的方法是:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
break
|
||||
|
||||
7、在Python2中,read()返回的是8-bit的字符串,而Python3以后统一是utf-8
|
||||
|
||||
8、标准输入输出:sys.stdin,sys.stdout,sys.stderr。和C中是对应的。如果直接用,可以
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import sys
|
||||
sys.stdin.write("What's your name:")
|
||||
name = sys.stdin.readline("")
|
||||
|
||||
9、当然如果从stdin读取,写入stdout也不用那么麻烦,用raw_input和print
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import sys
|
||||
name = raw_input("What's your name:")
|
||||
|
||||
10、print语句,尽管我们都是用它向stdout输出,但实际上它也可以用于File-Object的。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
f = open("output","w")
|
||||
print >>f,"hello world"
|
||||
|
||||
11、print语句在使用,隔开之后,默认的分隔符是空格,我们可以改变的:
|
||||
(但是我一直没执行成功的说。。。)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
f = open("output","w")
|
||||
print("The values are",x,y,z,sep=",")
|
||||
|
||||
12、print的字符串中的变量可使用“模板替换”。一般来说,web框架都有自己定义的一套模板语法和文件,但基本的用法还是可以用的:
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
text = "Dear %(name)s, Give me $%(amount)0.2f"
|
||||
print text % ( {"name":'Mrs. Liu', "amount":100.3} )
|
||||
|
||||
也可以用formart方法
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
text = "Dear {name}s, Give me {amount:0.2f}"
|
||||
print text.format( name='Mrs. Liu', amount=100.3)
|
||||
|
||||
13、Generater和I/O
|
||||
一般来说用生成器Generator与I/O操作结合,可以让内容的产生和I/O部分去耦合,另外附带的好处就是内存消耗更小(因为不是拼接好一堆string后再写入)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import sys
|
||||
#产生内容
|
||||
def content(n):
|
||||
while n > 0:
|
||||
yield "T-minus %d\n" % n
|
||||
n -= 1
|
||||
yield "HaHa"
|
||||
|
||||
#逐行写入,不费内存
|
||||
ct = content(5)
|
||||
f = sys.stdout
|
||||
f.writelines(ct)
|
||||
|
||||
14、显然,Generator对buffer的利用不是最大化的,因此,有些时候我们也会采取拼接大字符串再一次性写入的方法。拼接可以用join:
|
||||
(当然内存少不了。。)
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
......
|
||||
"".join(lines)
|
||||
|
||||
15、Unicode字符串的处理。
|
||||
绝对不要把unicode字符串和非unicode字符串连用!
|
||||
在I/O操作时,会遇到很多的Unicode问题。解决方法有很多:
|
||||
(1)通过encode和decode
|
||||
s.decode(encoding,error) 将encoding编码的字符串转化为unicode编码字符串
|
||||
s.encode(encoding,error) 将unicode编码的字符串转化为8-bit的、encoding格式的字节码
|
||||
encoding可以取ascii latin-1(iso-8859-1) cp1252 utf-8 utf-16 utf-16-le utf-16-be unicode-escape
|
||||
raw-unicode-escape等。
|
||||
error是转化过程中的容错级别,默认是strict,可以选择ignore或者replace等。
|
||||
(2)使用Unicode I/O
|
||||
使用函数codes.open(filename,mode,encoding,error),后三个参数可选。
|
||||
mode和open的mode类似。
|
||||
encoding是指定read和write时的字符串编码
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#这个例子要写入utf-8编码的字符串到文件
|
||||
>>> import codecs
|
||||
>>> str = u"计算所"
|
||||
>>> f = codecs.open("test.txt",'w','utf-8')
|
||||
>>> f.write(str)
|
||||
>>> f.close()
|
||||
#这个则是ascii编码(gbk)的
|
||||
>>> import codecs
|
||||
>>> str = "计算所"
|
||||
>>> f = codecs.open("test.txt",'w')
|
||||
>>> f.write(str)
|
||||
>>> f.close()
|
||||
|
||||
16、如果已经打开了一个文件,并且想用codecs,则可以用codecs包装一下:
|
||||
fenc = codecs.EncodedFile(f,”utf-8″)
|
||||
|
||||
17、Object序列化(持久化)。
|
||||
Python中,对Object进行持久化非常容易,可以用pickle实现:
|
||||
一个比较虎的地方貌似是支持循环引用。。比如下面的例子,我持久化o2,会把引用的o1也自动持久化了。。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
#!/usr/bin/python
|
||||
|
||||
import pickle
|
||||
|
||||
class MyObj(object):
|
||||
def __init__(self,v,r):
|
||||
self.value = v
|
||||
self.ref = r
|
||||
|
||||
def print123(self):
|
||||
print self.value
|
||||
if self.ref != None:
|
||||
print self.ref.value
|
||||
|
||||
if __name__ == "__main__":
|
||||
o1 = MyObj(1,None)
|
||||
o2 = MyObj(3,o1)
|
||||
|
||||
print "Before store using pickle"
|
||||
o2.print123()
|
||||
|
||||
f = open("obj.sav","wb")
|
||||
pickle.dump(o2,f)
|
||||
f.close()
|
||||
|
||||
print "After load using pickle"
|
||||
f = open("obj.sav","rb")
|
||||
o = pickle.load(f)
|
||||
f.close()
|
||||
o.print123()
|
||||
|
||||
18、对象的持久化还可以直接使用shelve,他不用再open文件了。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import shelve
|
||||
obj = SomeObject()
|
||||
db = shelve.open("file")
|
||||
db['key'] = obj
|
||||
...
|
||||
obj = db['key']
|
||||
db.close()
|
||||
|
||||
19、实际上,shelve的底层使用了pickle模块,只不过将它写成文件时更易读懂。pickle的持久化格式随着版本有细微差异,可以用过dump(obj,file,protocol)的最后一个参数来解决。
|
||||
|
||||
20、如果希望自定义持久化的数据,可以来重写对象的__getstate__() 和 __setstate__()。它们会被pickle再dump和load的时候调用。比如对象涉及底层网络socket的时候就是一个例子。
|
||||
|
||||
?
|
||||
#相关代码, [四号程序员] http://www.coder4.com
|
||||
import socket
|
||||
class Client(object):
|
||||
def __init__(self,addr):
|
||||
self.server_addr = addr
|
||||
self.sock = socket.Socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
self.sock.connect(addr)
|
||||
def __getstate__(self):
|
||||
return self.server_addr
|
||||
def __setstate(self,value):
|
||||
self.server_addr = value
|
||||
self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
self.sock.connect(self.server_addr)
|
||||
Reference in New Issue
Block a user