• 1. Python函数Python 学习小组 20160604
  • 2. Python中使用def关键字定义函数,函数包括函数名称和参数,不需要定义返回类型,Python能返回任何类型:函数的定义#没有返回值的函数,其实返回的是None   def run(name):          print name,'runing'  #函数体语句从下一行开始,并且第一行必须是缩进的      >>>run('xiaoming')   xiaoming runing      >>>print run('xiaoming')   xiaoming runing    None #如果没有ruturn语句,函数返回的是None    #有返回值的参数   def run(name):          return name+'runing‘    >>>r = run('xiaoming')   >>>r   xiaoming runing  
  • 3. 按引用传递参数所有参数在Python里都是按引用传递。如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:# 可写函数说明   def changeme( mylist ):      "修改传入的列表"      mylist.append([1,2,3,4]);      print "函数内取值: ", mylist      return       # 调用changeme函数   mylist = [10,20,30];   changeme( mylist );   print "函数外取值: ", mylist 运行结果: 函数内取值:  [10, 20, 30, [1, 2, 3, 4]]   函数外取值:  [10, 20, 30, [1, 2, 3, 4]]  
  • 4. def printme(age,str):       str = 'str changed!'       print “函数内:”,age,str       return      str = 'ori str'   age = 23   printme(age,str)   print  ‘=============’ print ‘age is’,age  print ‘str is’,str   奇怪的现象结果: 函数内:23 str changed!  ================  age is:23 str is: ori str 
  • 5. python中不存在所谓的传值调用,一切传递的都是对象的引用,也可以认为是传址。 python中,对象分为可变(mutable)和不可变(immutable)两种类型,元组(tuple)、数值型(number)、字符串(string)均为不可变对象,而字典型(dictionary)和列表型(list)的对象是可变对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。 想修改不可更改的对象时,其实就开辟了一个新的存储空间新的对象,由此引出全局作用域和局部作用域的问题
  • 6. 不可变类型特点: >>>a = 1 #将名字a与内存中值为1的内存绑定在一起 >>>a = 2 #将名字a与内存中值为2的内存绑定在一起,而不是修改原来a绑定的内存中的值,这时,内存中值为1的内存地址引用计数-1,当引用计数为0时,内存地址被回收 >>>b = a #变量b执行与a绑定的内存 >>>b = 3 #创建一个内存值为3的内存地址与变量名字b进行绑定。这是a还是指向值为2的内存地址。 >>>a,b >>>(2,3)   这种机制的好处有哪些,弊端有哪些?
  • 7. >>>x = 1 >>>y = 1 >>>x = 1 >>> x is y True >>>y is z True如上所示,因为整数为不可变,x,y,z在内存中均指向一个值为1的内存地址,也就是说,x,y,z均指向的是同一个地址不可变对象的优缺点:  优点:这样可以减少重复的值对内存空间的占用。  缺点:前面例子所示,要修改这个变量绑定的值,如果内存中没用存在该值的内存块,那么必须重新开辟一块内存,把新地址与变量名绑定。而不是修改变量原来指向的内存块的值,这回给执行效率带来一定的降低
  • 8. 可变对象的例子: >>>a = [1] >>>b = a #由于列别是可变对象类型,所以传递的时候,与变量名d绑定的内存地址与a绑定的内存地址是同一地址,内存里的值是[1] >>>b[0] = 2 >>>a [2]   如上所示:变量名a和b是绑定的同一内存地址,对任一个变量对应的值得改变,都会反映到另一个变量上。
  • 9. 变量作用域一个程序的所有的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。 变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。 全局变量 局部变量定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。 调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。
  • 10. total = 0; # 这是一个全局变量 # 可写函数说明 def sum( arg1, arg2 ): #返回2个参数的和." total = arg1 + arg2; # total在这里是局部变量. print "函数内是局部变量 : ", total return total; #调用sum函数 sum( 10, 20 ); print "函数外是全局变量 : ", total 函数内是局部变量 : 30 函数外是全局变量 : 0
  • 11. Python的函数的参数列表可以是任意多个,调用函数的时候,采取位置绑定和关键字绑定两种方式,确认传入的变量对应的参数!   上面演示的代码,都可以看作是位置绑定 。 下面看一下关键字绑定 :参数:def run(name,age,sex):          print 'name :',name,'age:',age,'sex:',sex   >>> run(age=23,name='xiaoming',sex='boy')#关键字绑定  name:xiaoming age:23 sex:boy  
  • 12. 某个参数不能在一次调用中同时使用位置和关键字绑定def run(name,age,sex):          print 'name :',name,'age:',age,'sex:',sex    >>> run('xiaoming',name='xiaoming',sex='boy')   SyntaxError: non-keyword arg after keyword arg   函数调用的时候,如果第一个参数使用了关键字绑定,后面的参数也必须使用关键字绑定!
  • 13. def run(name,age=20,sex='girl'):          print name,age,sex   >>>run('nana')   nana 20 girl   >>>run('nana',23)   nana 23 girl   >>>run('gg','boy')#使用的位置绑定,所以,python为将'boy'绑定在age上,而不是我们想要的sex上   gg boy girl      >>>run('gg',sex='boy')#混合关键字绑定,可以实现想要的效果   gg 20 boy  默认参数 
  • 14. 如果一个函数的参数中含有默认参数,则这个默认参数后的所有参数都必须是默认参数 ,否则会抛出:SyntaxError: non-default argument follows default argument的异常。def run(name,age=10,sex):          print name ,age ,sex   SyntaxError: non-default argument follows default argument gg 23 boy  
  • 15. def run(name,age,sex='boy'):          print name,age,sex      >>>run()#required argument missing   >>>run(name='gg',23)#non-keyword argument following keyword   >>>run('gg',name='pp')#duplicate value for argument   >>>run(actor='xxxx')#unknown keyword      #第一种情况是丢失参数   #第二种情况是:如果第一个使用了keyword绑定,后面的都必须使用keyword绑定   #第三种情况:在一次调用中不能同时使用位置和keyword绑定   #第四种情况:不能使用参数列表外的关键字  
  • 16. 不定长参数 Python的函数定义中有两种特殊的情况,即出现*,**的形式。 如:def myfun1(username, *keys)或def myfun2(username, **keys)等。 解释: * 用来传递任意个无名字参数,这些参数会一个Tuple的形式访问。 **用来处理传递任意个有名字的参数,这些参数用dict来访问。 其中 * 表示的是元祖或是列表,而 ** 则表示字典一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。
  • 17. >>> def fun1(*keys): ... print "keys type=%s" % type(keys) ... print "keys=%s" % str(keys) ... for i in range(0, len(keys)): ... print "keys[" + str(i) + "]=%s" % str(keys[i]) ... >>> fun1(2,3,4,5) 输出以下结果: keys type=tuple keys=(2, 3, 4, 5) keys[0]=2 keys[1]=3 keys[2]=4 keys[3]=5“*” 的应用
  • 18. “**” 的应用>>> def fun2(**keys): ... print "keys type=%s" % type(keys) ... print "keys=%s" % str(keys) ... print "name=%s" % str(keys['name']) ... >>>  >>> fun2(name="vp", age=19) 输出以下结果: keys type= keys={'age': 19, 'name': 'vp'} name=vp
  • 19. def fun_var_args(farg, *args):     print 'args:', farg     for value in args:         print 'another arg:',value # *args可以当作可容纳多个变量组成的list或tuple fun_var_args(1, 'two', 3, None) #args: 1 #another arg: two #another arg: 3 #another arg: None# 当函数的参数不确定时,可以使用*args和**kwargs。 *args没有key值(位置绑定), **kwargs有key值(关键字绑定)
  • 20. def fun_var_kwargs(farg, **kwargs):     print 'args:',farg     for key in kwargs:         print 'another keyword arg:%s:%s' % (key, kwargs[key]) # myarg1,myarg2和myarg3被视为key, **kwargs可以当作容纳多个key和value的dictionary fun_var_kwargs(1, myarg1='two', myarg2=3, myarg3=None) # 输出: #args: 1 #another keyword arg:myarg1:two #another keyword arg:myarg2:3 #another keyword arg:myarg3:None
  • 21. def fun_args(arg1, arg2, arg3):     print 'arg1:', arg1     print 'arg2:', arg2     print 'arg3:', arg3 mykwargs = {'arg1': '1', 'arg2': 'two', 'arg3': None}       # 定义字典类型 fun_args(**mykwargs) # 输出: #arg1: 1 #arg2: two #arg3: Nonemyargs = ['1', 'two', None]     # 定义列表 fun_args(*myargs) # 输出: #arg1: 1 #arg2: two #arg3: None
  • 22. args = [1, 2, 3, 4] kwargs = {'name': 'BeginMan', 'age': 22} fun_args_kwargs(args,kwargs) # args: ([1, 2, 3, 4], {'age': 22, 'name': 'BeginMan'}) # kwargs: {} fun_args_kwargs(1,2,3,a=100) #args: (1, 2, 3) #kwargs: {'a': 100} fun_args_kwargs(*(1,2,3,4),**{'a':None}) #args: (1, 2, 3, 4) #kwargs: {'a': None}# 两者都有 def fun_args_kwargs(*args, **kwargs):     print 'args:', args     print 'kwargs:', kwargs
  • 23. 必备参数必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。 调用printme()函数,你必须传入一个参数,不然会出现语法错误:#可写函数说明 def printme( str ): "打印任何传入的字符串" print str; return; #调用printme函数 printme();实际输出结果: Traceback (most recent call last): File "test.py", line 11, in printme(); TypeError: printme() takes exactly 1 argument (0 given)
  • 24. return语句return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。def sum( arg1, arg2 ):    # 返回2个参数的和."    total = arg1 + arg2    print "Inside the function : ", total    return total; # 调用sum函数 total = sum( 10, 20 ); print "Outside the function : ", total   #以上实例输出结果: #Inside the function :  30 #Outside the function :  30
  • 25. 类型转换函数—字符串chr(i):chr()函数返回ASCII码对应的字符串 ord(x):ord()函数返回一个字符串参数的ASCII码或Unicode值 。 str(obj):str()函数把对象转换成可打印字符串。
  • 26. map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。 比如,一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:>>> def f(x): ... return x * x >>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) [1, 4, 9, 16, 25, 36, 49, 64, 81]map()函数
  • 27. reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)但是如果要把序列[1, 3, 5, 7, 9]变换成整数13579,reduce就可以派上用场:reduce()函数
  • 28. Python内建的filter()函数用于过滤序列。filter()也接收一个函数和一个序列。 filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。filter()函数在一个list中,删掉偶数,只保留奇数,可以这么写def is_odd(n): return n % 2 == 1 filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]) # 结果: [1, 5, 9, 15]
  • 29. zip()函数可把两个或多个序列中的相应项合并在一起,并以元组的格式返回它们,在处理完最短序列中的所有项后就停止。>>> zip([1,2,3],[4,5],[7,8,9]) [(1, 4, 7), (2, 5, 8)]如果参数是一个序列,则zip()会以一元组的格式返回每个项,如:>>> zip((1,2,3,4,5)) [(1,), (2,), (3,), (4,), (5,)] >>> zip([1,2,3,4,5]) [(1,), (2,), (3,), (4,), (5,)]zip()函数
  • 30. enumerate()函数enumerate函数用于遍历序列中的元素以及它们的下标>>> for i,j in enumerate(('a','b','c')): print i,j 0 a 1 b 2 c>>> for i,j in enumerate('abc'): print i,j 0 a 1 b 2 c
  • 31. 列表生成式列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用range(1, 11):>>> range(1, 11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做>>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来
  • 32. for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方>>> [x * x for x in range(1, 11) if x % 2 == 0] [4, 16, 36, 64, 100]还可以使用两层循环,可以生成全排列:>>> [m + n for m in 'ABC' for n in 'XYZ'] ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
  • 33. Lambda函数(匿名函数)lambda语句被用来创建新的函数对象,并且在运行时返回它们。 语法 lambda x:表达式 lambda函数可看做仅有一个参数的特殊函数,后面必须是表达式,也可调用别的函数。 g=lambda x:x*2 g(3) g(“abcd”)
  • 34. 用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。 Lambda函数能接收任何数量的参数但只能返回一个表达式的值,同时只能不能包含命令或多个表达式。 匿名函数不能直接调用print,因为lambda需要一个表达式。 lambda函数拥有自己的名字空间,且不能访问自有参数列表之外或全局名字空间里的参数。 lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
  • 35. #可写函数说明 sum = lambda arg1, arg2: arg1 + arg2 #调用sum函数 print "Value of total : ", sum( 10, 20 ) print "Value of total : ", sum( 20, 20 ) #以上实例输出结果: #Value of total :  30 #Value of total :  40
  • 36. 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数>>> def now(): ... print '2013-12-25' >>> f = now >>> f() 2013-12-25假设要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。 decorator就是一个返回函数的高阶函数装饰器
  • 37. 我们要定义一个能打印日志的decorator,可以定义如下因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。 我们要借助Python的@语法,把decorator置于函数的定义处:装饰器
  • 38. 调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志:把@log放到now()函数的定义处,相当于执行了语句 now = log(now) 装饰器
  • 39. 如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本装饰器
  • 40. 这个3层嵌套的decorator用法如下:执行结果如下:装饰器
  • 41. (本页无文本内容)
  • 42.  迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问一遍后结束。   迭代器不能回退,只能往前进行迭代。这并不是什么很大的缺点,因为人们几乎不需要在迭代途中进行回退操作。   迭代器(Iterator)概述对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值)。 但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。
  • 43. Iterator是迭代器的意思,它的作用是一次产生一个数据项,直到没有为止。 这样在 for 循环中就可以对它进行循环处理了。那么它与一般的序列类型(list, tuple等)有什么区别呢? 它一次只返回一个数据项,占用更少的内存。但它需要记住当前的状态,以便返回下一数据项。 它是一个有着next()方法的对象。而序列类型则保存了所有的数据项,它们的访问是通过索引进行的。迭代器(Iterator)概述
  • 44.  迭代器的另一个优点就是它不要求事先准备好整个迭代过程中所有的元素。 迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。 这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。   迭代器更大的功劳是提供了一个统一的访问集合的接口。只要是实现了__iter__()方法的对象,就可以使用迭代器进行访问。Python专门将关键字for用作了迭代器的语法糖。迭代器(Iterator)概述
  • 45. 在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。 上述代码可以写成如下的形式:for val in lst:     print val首先Python将对关键字in后的对象调用iter函数获取迭代器,然后调用迭代器的next方法获取元素,直到抛出StopIteration异常。 对迭代器调用iter函数时将返回迭代器自身,所以迭代器也可以用于for语句中,不需要特殊处理。 常用的几个内建数据结构tuple、list、set、dict都支持迭代器,字符串也可以使用迭代操作。 也可以自己实现一个迭代器,如上所述,只需要在类的__iter__方法中返回一个对象,这个对象拥有一个next()方法,这个方法能在恰当的时候抛出StopIteration异常即可。迭代器(Iterator)概述
  • 46. 生成器生成器函数返回生成器的迭代器。这可能是你最后一次见到“生成器的迭代器”这个术语了, 因为它们通常就被称作“生成器”。 要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法(method),其中一个就是__next__()。如同迭代器一样,我们可以使用next()函数来获取下一个值在Python中,这种一边循环一边计算的机制,称为生成器(Generator)生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。 生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
  • 47. 通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。 而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。生成器就是一种迭代器。生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Python的for循环中。另外,对于生成器的特殊语法支持使得编写一个生成器比自定义一个常规的迭代器要简单不少,所以生成器也是最常用到的特性之一。生成器
  • 48. 要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:如果要一个一个打印出来,可以通过generator的next()方法生成器
  • 49. generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
  • 50. 不断调用next()方法实在是太麻烦,正确的方法是使用for循环,因为generator也是可迭代对象创建了一个generator后,基本上永远不会调用next()方法,而是通过for循环来迭代它生成器
  • 51. 定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:def fib(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:   1, 1, 2, 3, 5, 8, 13, 21, 34, ...要把fib函数变成generator,只需要把print b改为yield b就可以了:def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1生成器
  • 52. 如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generatorgenerator和函数的执行流程不一样。 函数是顺序执行,遇到return语句或者最后一行函数语句就返回。 而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令生成器
  • 53. 1 2 3 4 5 6 7 8 9 10 11 12 13>>> def fibonacci(): ...   a = b = 1 ...   yield a ...   yield b ...   while True: ...     a, b = b, a+b ...     yield b ... >>> for num in fibonacci(): ...   if num > 100: break ...   print num, ... 1 1 2 3 5 8 13 21 34 55 89看到while True可别太吃惊,因为生成器可以挂起,所以是延迟计算的,无限循环并没有关系。这个例子中我们定义了一个生成器用于获取斐波那契数列。http://python.jobbole.com/82163/生成器
  • 54. (本页无文本内容)
  • 55. ConfigParserconfigParser 是用来读取配置文件的包。 配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。1: [db] 2: db_host = 127.0.0.1 3: db_port = 22 4: db_user = root 5: db_pass = rootroot 7: [concurrent] 8: thread = 10 9: processor = 20 中括号“[ ]”内包含的为section。紧接着section 为类似于key-value 的options 的配置内容。
  • 56. 使用ConfigParser 首选需要初始化实例,并读取配置文件:1: cf = ConfigParser.ConfigParser() 2: cf.read("配置文件名")ConfigParser 初始工作及常用方法获取所有sections 也就是将配置文件中所有“[ ]”读取到列表中:1: s = cf.sections() 2: print 'section:', s 1: section: ['db', 'concurrent']
  • 57. 2. 获取指定section 的options 即将配置文件某个section 内key 读取到列表中:1: o = cf.options("db") 2: print 'options:', o 1: options: ['db_host', 'db_port', 'db_user', 'db_pass'] 3. 获取指定section 的配置信息1: v = cf.items("db") 2: print 'db:', v 1: db: [('db_host', '127.0.0.1'), ('db_port', '22'), ('db_user', 'root'), ('db_pass', 'rootroot')]ConfigParser
  • 58. 4. 按照类型读取指定section 的option 信息 2: db_host = cf.get("db", "db_host") 3: db_port = cf.getint("db", "db_port") 4: db_user = cf.get("db", "db_user") 5: db_pass = cf.get("db", "db_pass") 11: print "db_host:", db_host 12: print "db_port:", db_port 13: print "db_user:", db_user 14: print "db_pass:", db_pass 1: db_host: 127.0.0.1 2: db_port: 22 3: db_user: root 4: db_pass: rootroot ConfigParser
  • 59. 5. 设置某个option 的值。(记得最后要写回) 1: cf.set("db", "db_pass", "zhaowei") 2: cf.write(open("test.conf", "w")) 6.添加一个section。(同样要写回) 1: cf.add_section('liuqing') 2: cf.set('liuqing', 'int', '15') 3: cf.set('liuqing', 'bool', 'true') 4: cf.set('liuqing', 'float', '3.1415') 5: cf.set('liuqing', 'baz', 'fun') 6: cf.set('liuqing', 'bar', 'Python') 7: cf.set('liuqing', 'foo', '%(bar)s is %(baz)s') 8: cf.write(open("test.conf", "w")) ConfigParser
  • 60. 7. 移除section 或者option 。(只要进行了修改就要写回的哦) 1: cf.remove_option('liuqing','int') 2: cf.remove_section('liuqing') 3: cf.write(open("test.conf", "w")) ConfigParser 支持对%(value)s变量的解析conf.set("portal", "url2", "%(host)s:%(port)s") ConfigParser
  • 61. IO操作open 函数你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。各个参数: file_name:file_name变量是一个包含了你要访问的文件名称的字符串值 access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。 buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
  • 62. 模式描述r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。r+打开一个文件用于读写。文件指针将会放在文件的开头。rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。w打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。wb以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。w+打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。wb+以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
  • 63. 一个文件被打开后,你有一个file对象,你可以得到有关该文件的各种信息。 以下是和file对象相关的所有属性的列表:属性描述file.closed返回true如果文件已被关闭,否则返回false。file.mode返回被打开文件的访问模式。file.name返回文件的名称。file.softspace如果用print输出后,必须跟一个空格符,则返回false。否则返回true。IO操作
  • 64. 文件名: foo.txt 是否已关闭 : False 访问模式 : wb 末尾是否强制加空格 : 0IO操作
  • 65. close()方法File 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。 当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。# 打开一个文件 fo = open("foo.txt", "wb") print "文件名: ", fo.name # 关闭打开的文件 fo.close()
  • 66. write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。 write()方法不会在字符串的结尾添加换行符('\n'): 语法: fileObject.write(string);# 打开一个文件 fo = open("foo.txt", "wb") fo.write( "www.runoob.com!\nVery good site!\n"); # 关闭打开的文件 fo.close()write()方法
  • 67. read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。 语法: fileObject.read([count]); 被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾# 打开一个文件 fo = open("foo.txt", "r+") str = fo.read(10); print "读取的字符串是 : ", str # 关闭打开的文件 fo.close()读取的字符串是 : www.runoobread()方法
  • 68. .read() 每次读取整个文件,它通常将读取到底文件内容放到一个字符串变量中,也就是说 .read() 生成文件内容是一个字符串类型.readline()每只读取文件的一行,通常也是读取到的一行内容放到一个字符串变量中,返回str类型,.readlines()每次按行读取整个文件内容,将读取到的内容放到一个列表中,返回list类型,write(str)的参数是一个字符串,就是你要写入文件的内容. writelines(sequence)的参数是序列,比如列表,它接收一个字符串列表作为参数,将他们写入到文件中,换行符不会自动的加入,因此,需要显式的加入换行符。
  • 69. tell()方法告诉你文件内的当前位置;换句话说,下一次的读写会发生在文件开头这么多字节之后。 seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。 如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。文件定位
  • 70. # 打开一个文件 fo = open("foo.txt", "r+") str = fo.read(10); print "读取的字符串是 : ", str # 查找当前位置 position = fo.tell(); print "当前文件位置 : ", position # 把指针再次重新定位到文件开头 position = fo.seek(0, 0); str = fo.read(10); print "重新读取字符串 : ", str # 关闭打开的文件 fo.close()读取的字符串是 : www.runoob 当前文件位置 : 10 重新读取字符串 : www.runoob
  • 71. Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。 rename()方法需要两个参数,当前的文件名和新文件名。 语法:os.rename(current_file_name, new_file_name)import os # 重命名文件test1.txt到test2.txt。 os.rename( "test1.txt", "test2.txt" )重命名和删除文件
  • 72. 你可以用remove()方法删除文件,需要提供要删除的文件名作为参数。 语法: os.remove(file_name)os模块有许多方法能帮你创建,删除和更改目录。 os模块的mkdir()方法在当前目录下创建新的目录 语法: os.mkdir("newdir")remove()方法
  • 73. 可以用chdir()方法来改变当前的目录。 chdir()方法需要的一个参数是你想设成当前目录的目录名称。 语法: os.chdir("newdir")下例将进入"/home/newdir"目录。 import os # 将当前目录改为"/home/newdir" os.chdir("/home/newdir")chdir()方法
  • 74. getcwd()方法显示当前的工作目录 语法: os.getcwd() 例子: 下例给出当前目录: import os # 给出当前的目录 os.getcwd()rmdir()方法删除目录,目录名称以参数传递。 在删除这个目录之前,它的所有内容应该先被清除。 语法: os.rmdir('dirname') 例子: 以下是删除" /tmp/test"目录的例子。目录的完全合规的名称必须被给出,否则会在当前目录下搜索该目录。 import os # 删除”/tmp/test”目录 os.rmdir( "/tmp/test" )getcwd()方法、rmdir()方法
  • 75. 如果文件打开成功,接下来,调用read()方法可以一次读取文件的全部内容 >>> f.read() 'Hello, world!‘ 最后一步是调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:   >>> f.close() 由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:try: f = open('/path/to/file', 'r') print f.read() finally: if f: f.close()with语句
  • 76. 但是每次都这么写实在太繁琐,所以,Python引入了with语句来自动帮我们调用close()方法:   with open('/path/to/file', 'r') as f: print f.read() 这和前面的try ... finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法。with open('/Users/michael/test.txt', 'w') as f: f.write('Hello, world!')
  • 77. 变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,flattening等等   序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。   反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。   Python提供两个模块来实现序列化:cPickle和pickle。 这两个模块区别在于cPickle是C语言写的,速度快,pickle是纯Python写的,速度慢。用的时候,先尝试导入cPickle,如果失败,再导入pickle:序列化
  • 78. 尝试把一个对象序列化并写入文件:   >>> d = dict(name='Bob', age=20, score=88) >>> pickle.dumps(d) "(dp0\nS'age'\np1\nI20\nsS'score'\np2\nI88\nsS'name'\np3\nS'Bob'\np4\ns.“ pickle.dumps()方法把任意对象序列化成一个str,然后,就可以把这个str写入文件。 或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object:   >>> f = open('dump.txt', 'wb') >>> pickle.dump(d, f) >>> f.close()序列化
  • 79. 当要把对象从磁盘读到内存时,可以先把内容读到一个str,然后用pickle.loads()方法反序列化出对象, 也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象。   >>> f = open('dump.txt', 'rb') >>> d = pickle.load(f) >>> f.close() >>> d {'age': 20, 'score': 88, 'name': 'Bob'}序列化
  • 80. 要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML 更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。 JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。序列化 JSON格式Python内置的json模块提供了非常完善的Python对象到JSON格式的转换。
  • 81. 用loads()或者对应的load()方法把JSON反序列化,前者把JSON的字符串反序列化,后者从file-like Object中读取字符串并反序列化: >>> json_str = '{"age": 20, "score": 88, "name": "Bob"}' >>> json.loads(json_str) {u'age': 20, u'score': 88, u'name': u'Bob'} 需要注意一点:反序列化得到的所有字符串对象默认都是unicode而不是str。 JSON标准规定JSON编码是UTF-8,所以我们总是能正确地在Python的str或unicode与JSON的字符串之间转换。>>> import json >>> d = dict(name='Bob', age=20, score=88) >>> json.dumps(d) '{"age": 20, "score": 88, "name": "Bob"}‘ dumps()方法返回一个str,内容就是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like Object。序列化 JSON格式