1. 程式人生 > >Python基礎:Python函數、文件操作、遞歸

Python基礎:Python函數、文件操作、遞歸

文件處理 r+ lose 獲取 表示 pyw 全部 truncate 模塊

函數參數

函數參數包括位置參數,關鍵字參數,動態參數(*args, **args)三種。

傳參的過程是形式參數的賦值。

*args傳入的參數是元組形式,**args傳入的參數是字典形式。

示例代碼如下:(這部分直接看代碼實例會更清楚靜態參數與動態參數如何混用)

技術分享
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 # def story(**kwargs):
  4 #     return ‘Once upon a time,there was a ‘  5 #             ‘%(job)s called %(name)s.‘ % kwargs
  6
# print(story(job = ‘king‘,name = ‘bolen‘)) 7 # 8 # def power(x,y,*others): 9 # if others: 10 # print(‘received redundant parameters:‘,others) 11 # return pow(x,y) 12 # power(2,3,) 13 14 def interval(start,stop = None,step = 1): 15 if stop is None: 16 start,stop=0,start
17 result = [] 18 i = start 19 while i < stop: 20 result.append(i) 21 i+=step 22 return result 23 24 -----------------------shell excute------------------------------- 25 >>> story(job = ‘king‘,name = ‘bolen‘) 26 ‘Once upon a time,there was a king called bolen.‘ 27
>>> parms = {‘job‘:‘engineer‘,‘name‘:‘jack‘} 28 >>> story(**parms) 29 ‘Once upon a time,there was a engineer called jack.‘ 30 >>> del parms[‘job‘] 31 >>> parms 32 {‘name‘: ‘jack‘} 33 >>> story(job = ‘小王子‘,**parms) 34 ‘Once upon a time,there was a 小王子 called jack.‘ 35 36 >>> power(2,3) 37 8 38 >>> power(y=3,x=2) 39 8 40 >>> parms = (5,)*2 41 >>> type(parms) 42 <class ‘tuple‘> 43 >>> power(*parms) 44 3125 45 >>> parms 46 (5, 5) 47 48 49 >>> interval(10) 50 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 51 >>> interval(1,6) 52 [1, 2, 3, 4, 5] 53 >>> interval(2,12,3) 54 [2, 5, 8, 11] 55 >>> power(*interval(3,7)) 56 received redundant parameters: (5, 6) 57 81 58
函數參數示例


變量作用域

函數內部的變量稱為局部變量,全局無法訪問局部變量,函數內部正常也無法訪問全局變量,除非以如下方式:

函數內讀取全局變量:(慎重引用全局變量,容易出錯)

  1 >>> def com(para):
  2 	print(para+globals()[‘para‘])
  3 >>> com(‘yingying‘)
  4 yingyingbolen

函數內聲明全局變量:

  1 >>> def ch_global():
  2 	global x
  3 	x +=1
  4 >>> x =  1
  5 >>> ch_global()
  6 >>> x
  7 2


Python內置函數

技術分享

詳細介紹請點擊:官網內置函數詳解

Python文件操作:open函數和with open(管理上下文)

open函數用於文件處理。一般步驟是打開文件,然後操作文件。

  1 文件句柄 = open(‘文件路徑‘,‘模式‘)
  句柄是WONDOWS用來標識被應用程序所建立或使用的對象的唯一整數,WINDOWS使用各種各樣的句柄標識諸如應用程序實例,窗口,控制,位圖,GDI對象等等。
句柄是一個標識符,是拿來標識對象或者項目的,它就象我們的姓名一樣,每個人都會有一個,不同的人的姓名不一樣,但是,也可能有一個名字和你一樣的人。從數據類型上來看它只是一個16位的無符號整數。應用程序幾乎總是通過調用一個WINDOWS函數來獲得一個句柄,之後其他的WINDOWS函數就可以使用該句柄,以引用相應的對象。  

  文件句柄在文件I/O中,要從一個文件讀取數據,應用程序首先要調用操作系統函數並傳送文件名,並選一個到該文件的路徑來打開文件。該函數取回一個順序號,即文件句柄(file handle),該文件句柄對於打開的文件是唯一的識別依據。要從文件中讀取一塊數據,應用程序需要調用函數ReadFile,並將文件句柄在內存中的地址和要拷貝的字節數傳送給操作系統。當完成任務後,再通過調用系統函數來關閉該文件。

打開後獲得該文件句柄,後面通過此文件句柄對文件操作。

一、打開文件

打開文件的模式有:

  • r ,只讀模式【默認】
  • w,只寫模式【不可讀;不存在則創建;存在則清空內容;】
  • x, 只寫模式【不可讀;不存在則創建,存在則報錯】
  • a, 追加模式【可讀; 不存在則創建;存在則只追加內容;】

"+" 表示可以同時讀寫某個文件

  • r+, 讀寫【可讀,可寫】
  • w+,寫讀【可讀,可寫】
  • x+ ,寫讀【可讀,可寫】
  • a+, 寫讀【可讀,可寫】

"b"表示以字節的方式操作

  • rb 或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

註:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型。

二、文件操作

技術分享
  1 class TextIOWrapper(_TextIOBase):
  2     """
  3     Character and line based layer over a BufferedIOBase object, buffer.
  4 
  5     encoding gives the name of the encoding that the stream will be
  6     decoded or encoded with. It defaults to locale.getpreferredencoding(False).
  7 
  8     errors determines the strictness of encoding and decoding (see
  9     help(codecs.Codec) or the documentation for codecs.register) and
 10     defaults to "strict".
 11 
 12     newline controls how line endings are handled. It can be None, ‘‘,
 13     ‘\n‘, ‘\r‘, and ‘\r\n‘.  It works as follows:
 14 
 15     * On input, if newline is None, universal newlines mode is
 16       enabled. Lines in the input can end in ‘\n‘, ‘\r‘, or ‘\r\n‘, and
 17       these are translated into ‘\n‘ before being returned to the
 18       caller. If it is ‘‘, universal newline mode is enabled, but line
 19       endings are returned to the caller untranslated. If it has any of
 20       the other legal values, input lines are only terminated by the given
 21       string, and the line ending is returned to the caller untranslated.
 22 
 23     * On output, if newline is None, any ‘\n‘ characters written are
 24       translated to the system default line separator, os.linesep. If
 25       newline is ‘‘ or ‘\n‘, no translation takes place. If newline is any
 26       of the other legal values, any ‘\n‘ characters written are translated
 27       to the given string.
 28 
 29     If line_buffering is True, a call to flush is implied when a call to
 30     write contains a newline character.
 31     """
 32     def close(self, *args, **kwargs): # real signature unknown
 33         關閉文件
 34         pass
 35 
 36     def fileno(self, *args, **kwargs): # real signature unknown
 37         文件描述符
 38         pass
 39 
 40     def flush(self, *args, **kwargs): # real signature unknown
 41         刷新文件內部緩沖區
 42         pass
 43 
 44     def isatty(self, *args, **kwargs): # real signature unknown
 45         判斷文件是否是同意tty設備
 46         pass
 47 
 48     def read(self, *args, **kwargs): # real signature unknown
 49         讀取指定字節數據
 50         pass
 51 
 52     def readable(self, *args, **kwargs): # real signature unknown
 53         是否可讀
 54         pass
 55 
 56     def readline(self, *args, **kwargs): # real signature unknown
 57         僅讀取一行數據
 58         pass
 59 
 60     def seek(self, *args, **kwargs): # real signature unknown
 61         指定文件中指針位置
 62         pass
 63 
 64     def seekable(self, *args, **kwargs): # real signature unknown
 65         指針是否可操作
 66         pass
 67 
 68     def tell(self, *args, **kwargs): # real signature unknown
 69         獲取指針位置
 70         pass
 71 
 72     def truncate(self, *args, **kwargs): # real signature unknown
 73         截斷數據,僅保留指定之前數據
 74         pass
 75 
 76     def writable(self, *args, **kwargs): # real signature unknown
 77         是否可寫
 78         pass
 79 
 80     def write(self, *args, **kwargs): # real signature unknown
 81         寫內容
 82         pass
 83 
 84     def __getstate__(self, *args, **kwargs): # real signature unknown
 85         pass
 86 
 87     def __init__(self, *args, **kwargs): # real signature unknown
 88         pass
 89 
 90     @staticmethod # known case of __new__
 91     def __new__(*args, **kwargs): # real signature unknown
 92         """ Create and return a new object.  See help(type) for accurate signature. """
 93         pass
 94 
 95     def __next__(self, *args, **kwargs): # real signature unknown
 96         """ Implement next(self). """
 97         pass
 98 
 99     def __repr__(self, *args, **kwargs): # real signature unknown
100         """ Return repr(self). """
101         pass
102 
103     buffer = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
104 
105     closed = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
106 
107     encoding = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
108 
109     errors = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
110 
111     line_buffering = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
112 
113     name = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
114 
115     newlines = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
116 
117     _CHUNK_SIZE = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
118 
119     _finalizing = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
120 
121 3.x
Python3中的文件操作


三、管理上下文

由於文件讀寫時都有可能產生IOError,一旦出錯,後面的f.close()就不會調用。所以,為了保證無論是否出錯都能正確地關閉文件,我們可以使用try ... finally來實現:

  1 try:
  2     f = open(‘/path/to/file‘, ‘r‘)
  3     print(f.read())
  4 finally:
  5     if f:
  6         f.close()
  7 

但是每次都這麽寫實在太繁瑣,所以,Python引入了with語句來自動幫我們調用close()方法:

  1 with open(‘/path/to/file‘, ‘r‘) as f:
  2     print(f.read())
  3 

這和前面的try ... finally是一樣的,但是代碼更佳簡潔,並且不必調用f.close()方法。

在Python 2.7 及以後,with又支持同時對多個文件的上下文進行管理,即:

  1 with open(‘log1‘) as obj1, open(‘log2‘) as obj2:
  2 	pass
  3 
技術分享
  1 import sys
  2 import json
  3 with open (‘c:/Users/zliyong/filo.txt‘,‘a+‘,encoding=‘utf-8‘) as f:
  4     #f.write(‘first line\nsecondline\n3rd line\n 4rd line‘)
  5     # f.tell()#查看當前指針位置
  6     # f.seek(2)#指定當前指針位置
  7     ret = f.truncate(100) #從指定位置向前截取
  8     print(f.tell())
  9     print(f.read())
 10     for line in f.readlines():
 11         print(line.strip())
Python3中的文件操作實例

如果文件很小,read()一次性讀取最方便;如果不能確定文件大小,反復調用read(size)比較保險;如果是配置文件,調用readlines()最方便。

open()函數返回的這種有個read()方法的對象,在Python中統稱為file-like Object。除了file外,還可以是內存的字節流,網絡流,自定義流等等。file-like Object不要求從特定類繼承,只要寫個read()方法就行。

StringIO就是在內存中創建的file-like Object,常用作臨時緩沖。

二進制文件

前面講的默認都是讀取文本文件,並且是UTF-8編碼的文本文件。要讀取二進制文件,比如圖片、視頻等等,用‘rb‘模式打開文件即可:

  1 >>> f = open(‘/Users/michael/test.jpg‘, ‘rb‘)
  2 >>> f.read()
  3 b‘\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...‘ # 十六進制表示的字節
  4 
字符編碼

要讀取非UTF-8編碼的文本文件,需要給open()函數傳入encoding參數,例如,讀取GBK編碼的文件:

  1 >>> f = open(‘/Users/michael/gbk.txt‘, ‘r‘, encoding=‘gbk‘)
  2 >>> f.read()
  3 ‘測試‘
  4 

遇到有些編碼不規範的文件,你可能會遇到UnicodeDecodeError,因為在文本文件中可能夾雜了一些非法編碼的字符。遇到這種情況,open()函數還接收一個errors參數,表示如果遇到編碼錯誤後如何處理。最簡單的方式是直接忽略:

  1 >>> f = open(‘/Users/michael/gbk.txt‘, ‘r‘, encoding=‘gbk‘, errors=‘ignore‘)

寫文件註意事項:

可以反復調用f.write來進行寫文件,但是一定要記得用f.close來關閉文件。因為操作系統在往磁盤裏寫文件時,往往不會立即寫入磁盤,而是放在內存中緩存起來,待空閑了再慢慢進行寫操作,所以只有調用f.close()方法才能保證操作系統文件完整寫入到磁盤,否則經常會使文件部分寫入磁盤,剩下的丟失了。


操作文件和目錄

Python中的內置os模塊提供了調用系統接口函數的功能,實現簡單的系統操作。

  1 >>>import os
  2 >>>os.name()  #獲取操作系統名字
  3 ‘nt‘
  4 >>> os.environ #獲取操作系統全部的環境變量
  5 >>> os.environ.get(‘PATH‘)#獲取操作系統中某個環境變量的值
  6 
  7 
  8 

註意:操作文件和目錄的函數一部分放在os模塊中,一部分放在os.path模塊中。創建、刪除目錄,路徑拼接等可以如下調用:

  1 >>> os.path.abspath(‘.‘)
  2 ‘C:\\Users\\zliyong\\AppData\\Local\\Programs\\Python\\Python35‘
  3 >>> os.path.join(‘Users/zliyong‘,‘test.dir‘) #路徑拼接
  4 ‘Users/zliyong\\test.dir‘
  5 >>> os.mkdir(‘c:/Users/zliyong/test.dir‘)
  6 >>> os.rmdir(‘c:/Users/zliyong/test.dir‘)
  7 >>> os.path.split(‘c:/Users/zliyong/test.dir‘)
  8 (‘c:/Users/zliyong‘, ‘test.dir‘)
  9 >>> os.path.splitext(‘c:/Users/zliyong/test.dir/test.txt‘)
 10 (‘c:/Users/zliyong/test.dir/test‘, ‘.txt‘)
 11 >>> os.rename(‘c:/Users/zliyong/test.dir‘,‘c:/Users/zliyong/pyrename.dir‘)

但是復制文件的函數居然在os模塊中不存在!原因是復制文件並非由操作系統提供的系統調用。理論上講,我們通過上一節的讀寫文件可以完成文件復制,只不過要多寫很多代碼。

幸運的是shutil模塊提供了copyfile()的函數,你還可以在shutil模塊中找到很多實用函數,它們可以看做是os模塊的補充。

  1 import shutil
  2 >>> shutil.copyfile(‘c:/Users/zliyong/pyrename.dir/test.txt‘,‘c:/Users/zliyong/pyrename.dir/test2.txt‘)
  3 ‘c:/Users/zliyong/pyrename.dir/test2.txt‘

最後看看如何利用Python的特性來過濾文件。比如我們要列出當前目錄下的所有目錄,只需要一行代碼:

  1 >>> [x for x in os.listdir(‘.‘) if os.path.isdir(x)]
  2 [‘DLLs‘, ‘Doc‘, ‘include‘, ‘Lib‘, ‘libs‘, ‘Scripts‘, ‘tcl‘, ‘Tools‘]
  3 >>> [x for x in os.listdir(‘.‘) if os.path.isfile(x) and os.path.splitext(x)[1]==‘.py‘]
  4 []


lambda表達式

lambda表達式又稱為匿名函數,適用於某些簡單函數的語法糖。如下這個lambda表達式結合列表推導式的例子是很tricky的:

  1 >>> result = [lambda x: x + i for i in range(10)]
  2 >>> print(result[0](10))
  3 19
  4 >>> print(result)
  5 [<function <listcomp>.<lambda> at 0x000001D664C7C7B8>, <function <listcomp>.<lambda> at 0x000001D667100F28>, <function <listcomp>.<lambda> at 0x000001D667105048>, <function <listcomp>.<lambda> at 0x000001D6671050D0>, <function <listcomp>.<lambda> at 0x000001D667105158>, <function <listcomp>.<lambda> at 0x000001D6671051E0>, <function <listcomp>.<lambda> at 0x000001D667105268>, <function <listcomp>.<lambda> at 0x000001D6671052F0>, <function <listcomp>.<lambda> at 0x000001D667105378>, <function <listcomp>.<lambda> at 0x000001D667105400>]

首先執行range函數,然後生成10個lamda函,當調用result函數時i=9,所以result是一個10個元素都是19的列表。


遞歸

Python基礎:Python函數、文件操作、遞歸