人生苦短,我用python
基础数据集
list,tuple,dictionary
list list相当于数组1
2
3
4
5
6
7
8
9
li = [1 , 9 , 8 , 4 ]
li_reflect = [elem*2 for elem in li]
li = ['server=mpilgrim' , 'uid=sa' , 'database=master' , 'pwd=secret' ]
str1 = ';' .join(li)
str2 = str1.split(";" )
tuple tuple是不可修改的数据类型,一般用于定义常量
dictionary 字典数据类型,存储key-value类型数据1
2
3
4
5
6
params = {"server" :"mpilgrim" , "database" :"master" , "uid" :"sa" , "pwd" :"secret" }
params.values()
params.items()
["%s=%s" % (k, v) for k, v in params.items()]
自省 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def info (object, spacing=10 , collapse=1 ) : (1 ) (2 ) (3 )
"""Print methods and doc strings.
Takes module, class, list, dictionary, or string."""
methodList = [method for method in dir(object) if callable(getattr(object, method))]
processFunc = collapse and (lambda s: " " .join(s.split())) or (lambda s: s)
print "\n" .join(["%s %s" %
(method.ljust(spacing), processFunc(str(getattr(object, method).__doc__)))
for method in methodList])
if __name__ == "__main__" :
print info.__doc__
li = []
info(li)
"""append count extend index insert pop remove reverse sort
L.append(object) -- append object to end
L.count(value) -> integer -- return number of occurrences of value
L.extend(list) -- extend list by appending list elements L.index(value) -> integer -- return index of first occurrence of value
L.insert(index, object) -- insert object before index
L.pop([index]) -> item -- remove and return item at index (default last)
L.remove(value) -- remove first occurrence of value L.reverse() -- reverse *IN PLACE*
L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1"""
使用 type、str、dir 和其它内置函数 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type(1 )
li = []
type(li)
str(1 )
horsemen = ['war' , 'pestilence' , 'famine' ]
li = []
dir(li)
import string
string.punctuation
callable(string.punctuation)
callable(string.Template)
string.Template.__doc__
type、str、dir 和其它的 Python 内置函数都归组到了 builtin (前后分别是双下 划线) 这个特殊的模块中。如果有帮助的话,你可以认为 Python 在启动时自 动执行了 from builtin import *,此语句将所有的 “内置” 函数导入该命名空间, 所以在这个命名空间中可以直接使用这些内置函数
通过 getattr 获取对 象引用
使用 getattr 函数,可以得到一个直到运行时才知道名称的函数的引用。
1
2
3
4
5
li = ["Larry" , "Curly" ]
print (li.pop,getattr(li, "pop" ))
getattr(li, "append" )("Moe" )
getattr 作为一个分发者
getattr 常见的使用模式是作为一个分发者。举个例子,如果你有一个程序可以 以不同的格式输出数据,你可以为每种输出格式定义各自的格式输出函数, 然后使用唯一的分发函数调用所需的格式输出函数。例如,让我们假设有一个以 HTML、XML 和普通文本格式打印站点统计的程序。 输出格式在命令行中指定,或者保存在配置文件中。statsout 模块定义了三个 函数:output_html、output_xml 和 output_text。然后主程序定义了唯一的输出函数, 如下:
1
2
3
4
5
6
7
8
import statsout
def output (data, format="text" ) :
output_function = getattr(statsout, "output_%s" % format)
return output_function(data)
def output (data, format="text" ) :
output_function = getattr(statsout, "output_%s" % format, statsout.output_text)
return output_function(data)
过滤列表
Python 具有通过列表解析 (Section 3.6, “映射 list”) 将列表映射到 其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素 被映射的同时跳过另外一些元素。 过滤列表语法:[mapping-expression for element in source-list if filter-expression]
1
2
3
4
5
6
7
li = ["a" , "mpilgrim" , "foo" , "b" , "c" , "b" , "d" , "d" ]
[elem for elem in li if len(elem) > 1 ]
[elem for elem in li if elem != "b" ]
[elem for elem in li if li.count(elem) == 1 ]
methodList = [method for method in dir(object) if callable(getattr(object, method))]
and or 的用法
使用 and 时,在布尔环境中从左到右演算表达式的值。如果布尔环境中的某个值为假,则 and 返回第一个假值。所有值都为真,所以 and 返回最后一个真值
使用 or 时,在布尔环境中从左到右演算值,如果有一个值 为真,or立刻返回该值.如果所有的值都为假,or返回最后一个假值1
2
3
4
5
6
7
'a' and 'b'
'' and 'b'
'a' and 'b' and 'c'
'a' or 'b'
'' or 'b'
'' or [] or {}
使用 lambda 函数
Python 支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 lambda 的函数,是从 Lisp 借用来的,可以用在任何需要函数的地方。 总的来说,lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个 表达式的值。lambda 函数不能包含命令,包含的表达式不能超过一个。不要 试图向 lambda 函数中塞入太多的东西;如果你需要更复杂的东西,应该定义 一个普通函数,然后想让它多长就多长。
1
2
3
4
5
6
def f (x) :
return x*2
f(3 )
g = lambda x: x*2
g(3 )
(lambda x: x*2 )(3 )
对象和面向对象 导入模块
import module
from module import
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import copy
class User :
"""user class,include user info"""
def __init__ (self,name=None,age=None,dic=None) :
self.name = name
self.age = age
self.dic = {}
def __getitem__ (self,key) :
return self.dic[key]
def __setitem__ (self,key,value) :
self.dic[key] = value
user1 = User('chenxushan' ,24 )
user1.__setitem__('address' ,'suzhou' )
address = user1.__getitem__('address' )
user2 = copy.copy(user1)
print(address,user1.__doc__,user1.__class__,user2.__class__)
class Counter :
count = 0
def __init__ (self) :
self.__class__.count += 1
counter
counter.count
c = counter()
c.count
counter.count
d = counter()
d.count
c.count
counter.count
私有函数
与大多数的语言不同,一个 Python 函数,方法,或属性是私有还是公有,完 全取决于它的名字。举例来说 有两个方法:__parse 和 __setitem。正如我们已经讨论过的, \ setitem 是一个专有方法;通常,你不直接调用它,而是通过在一个类上使 用字典语法来调用,但它是公有的,并且如果有一个真正好的理由,你可以 直接调用它 (甚至从 fileinfo 模块的外面)。然而,\ parse 是私有的,因为在它的 名字前面有两个下划线。 在 Python 中,所有的专用方法 (像 __setitem) 和内置属性 (像 \ doc__) 遵守一 个标准的命名习惯:开始和结束都有两个下划线。不要对你自已的方法和属 性用这种方法命名;
异常和文件处理 异常
Python 使用 try…except 来处理异常,使用 raise 来引发异常。Java 和 C++ 使用 try…catch 来处理异常,使用 throw 来引发异常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import os
if __name__ == '__main__' :
try :
fsock = open('./text' ,'rb' )
except IOError:
print ("The file does not exist, exiting gracefully" )
else :
print ("This line will always print" )
fsock.seek(2 ,0 )
fsock.close()
class ReadFile :
def __init__ (self,filename = None) :
self.filename = filename
def read_file (self,filename = None, mode = None, postion = 0 ,counte = 0 ) :
try :
fsock = open(filename,mode)
try :
fsock.seek(postion)
tagdate = fsock.read(counte)
finally :
fsock.close()
except IOError:
pass
return tagdate
def write_file (self,filename = None,mode = None,method = None,content = None) :
try :
fsock = open(filename,mode)
try :
write_method = getattr(fsock,"%s" % method)
write_method(content)
finally :
fsock.close()
except IOError:
pass
f = ReadFile('./text' )
f.write_file('./text' ,'w' ,'write' ,'chenxuhsan' )
f.write_file('./text' ,'a' ,'write' ,"xuminrui" )
for 循环 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import os,sys
if __name__ == "__main__" :
li = ['a' ,'b' ,'c' ]
for item in range(len(li)):
print(li[item])
for k,v in os.environ.items():
pass
tagDataMap = {"title" :( 3 , 33 , 'stripnulls' ), "artist" :( 33 , 63 , 'stripnulls' ),\
"album" :( 63 , 93 , 'stripnulls' ),\
"year" :( 93 , 97 , 'stripnulls' ),\
"comment" :( 97 , 126 , 'stripnulls' ),\
"genre" :(127 , 128 , 'ord' )\
}
for tag, (start, end, parseFunc) in tagDataMap.items():
pass
for k,v in sys.modules.items():
print("%s=%s" %(k,v))
print(sys.modules['io' ])
目录操作 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import os
if __name__ == "__main__" :
path1 = os.path.join("/Users/chenxushan/Documents/SublimeWorkspace/python/base/" , "text.txt" )
print(path1,os.path.expanduser("~" ),os.path.join(os.path.expanduser("~" ), "Python" ))
(filepath, filename) = os.path.split('/Users/chenxushan/Documents/SublimeWorkspace/python/base/text.txt' )
(shortname, extension) = os.path.splitext(filename)
print(filepath,filename,shortname,extension)
dirname = './'
listdir = os.listdir(dirname)
isFile = [f for f in os.listdir(dirname) if os.path.isfile(os.path.join(dirname, f))]
isDir = [f for f in os.listdir(dirname) if os.path.isdir(os.path.join(dirname, f))]
print(listdir,isFile,isDir)
类
python类支持继承,也支持多继承
迭代器
for element in [1, 2, 3]: print(element) 这种形式的访问清晰、简洁、方便。迭代器的用法在 Python 中普遍而且统一。 在后台,for 语句在容器对象中调用 iter() 。该函数返回一个定义了 next() 方法的迭代器对象,它在容器中逐一访问元素。没有后续的元素时, next() 抛 出一个 StopIteration 异常通知 for 语句循环结束。以下是其工作原理的示 例:
1
2
3
s = 'abc'
it = iter(s)
next(it)
了解了迭代器协议的后台机制,就可以很容易的给自己的类添加迭代器行为。定 义一个 iter () 方法,使其返回一个带有 next() 方法的对象。如果这个类 已经定义了 next() ,那么 iter () 只需要返回 self:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Reverse :
"""Iterator for looping over a sequence backwards."""
def __init__ (self, data) :
self.data = data
self.index = len(data)
def __iter__ (self) :
return self
def __next__ (self) :
if self.index == 0 :
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
rev = Reverse('spam' )
iter(rev)
for char in rev:
print(char)
我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list、tuple、dict、set、str等; 一类是generator,包括生成器和带yield的generator function。 这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。 可以使用isinstance()判断一个对象是否是Iterable对象:
1
2
from collections import Iterable
isinstance([], Iterable)
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。可以使用isinstance()判断一个对象是否是Iterator对象:
1
2
from collections import Iterator
isinstance((x for x in range(10 )), Iterator)
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。把list、dict、str等Iterable变成Iterator可以使用iter()函数:
1
2
isinstance(iter([]), Iterator)
isinstance(iter('abc' ), Iterator)
为什么list、dict、str等数据类型不是Iterator? 这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。 Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。 要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
g = (x * x for x in range(10 ))
next(g)
next(g)
for n in g:
print(n)
def fib (max) :
n, a, b = 0 , 0 , 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
f = fib(6 )
def odd () :
print('step 1' )
yield 1
print('step 2' )
yield (3 )
print('step 3' )
yield (5 )
o = odd()
next(o)
g = fib(6 )
while True :
try :
x = next(g)
print('g:' , x)
except StopIteration as e:
print('Generator return value:' , e.value)
break
小结
凡是可作用于for循环的对象都是Iterable类型; 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列; 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。 Python的for循环本质上就是通过不断调用next()函数实现的,例如:
综合例子 遍历字典 1
2
3
4
5
6
7
8
9
10
11
12
def buildConnectionString (params) :
"""Build a connection string from a dictionary of parameters.
Returns string."""
return ";" .join(["%s=%s" % (k, v) for k, v in params.items()])
if __name__ == "__main__" :
myParams = {"server" :"mpilgrim" , \
"database" :"master" , \
"uid" :"sa" , \
"pwd" :"secret" \
}
print buildConnectionString(myParams)