第三天 函數 三元運算 lambda表達式 內置函數 文件操做

  面向過程:python

 

直接一行一行寫代碼,遇到重複的內容複製黏貼。app

 

不利於代碼閱讀函數

代碼沒有複用編碼

 

面向對象spa

 

將代碼塊定義爲函數,之後直接調用函數設計

 

加強了複用性指針

 

 

函數的定義方法對象

 

def 函數名(傳遞參數):ip

函數體內存

return

 

一、def關鍵字,建立函數

二、函數名

三、():

四、 函數體

五、返回值return

 

函數必須先定義,以後調用。不能反過來

 

在執行函數體的過程當中,一旦執行到return,則會當即退出函數,return以後的語句將不會被執行

 

當定義一個函數後,執行的時候會按照函數體進行執行,而且能夠將函數體的return賦值給變量

 

def f1():

函數體

return 111

r = f1()

 

print(r)   會顯示111

 

可是若是函數體中沒有寫return,python會自動給函數體返回一個默認值就是None

 

 

 

在執行函數的時候使用

try:

函數體

expect:

return False

else:

return True

 

會判斷函數體的執行結果,若是遇到錯誤就會執行expect裏的內容,不然會執行else,返回值能夠自定義

 

 

函數的參數

 

 

形式參數 在定義函數時,爲了可以讓調用時能夠輸入參數而設計的參數

 

實際參數 在調用函數時傳遞的參數

 

def f1(形式參數)

函數體

 

r = f1(實際參數)

 

調用時傳遞的實際參數數量須要與定義時定義的形式參數數量一致,形式參數能夠在同一個函數中定義多個,實際參數的傳遞順序也須要遵循形式參數的順序

 

集中傳遞參數的方式

 

函數有四類類參數

 

一、普通參數,按順序複製

二、默認參數,在定義函數時定義,可是在定義時python要求默認參數必須放在形式參數列表的最後

  

默認參數 在定義形式參數時能夠定義默認參數

 

def f2(xx,yy,zz="ok")

 

其中zz就是默認參數,在調用這個函數的時候,能夠傳遞三個參數也能夠僅傳遞2個參數,當三個參數時zz等於第三個參數,當兩個參數時zz等於默認值"ok"

 

 

三、指定參數,在調用函數時指定賦值參數的名字

指定參數必須在調用函數時放到最後,可是不容許重複賦值給同一個參數

 

指定參數,默認狀況下傳遞參數的順序是要嚴格按照形式參數的順序的,可是經過在調用時指定參數也能夠改變順序

 

def f3(xx,yy,zz)

 

f3(yy="11",zz="ok",xx="ye")

 

def f1(arg1,arg2,arg3)

pass

 

錯誤的指定參數

f1(arg1 = 2,arg2 =3,4) # 這是不行的

 

f1(4,arg2=3,arg1 =2) # 這也不行,由於至關於給arg1先賦值4 後賦值2 不容許重複賦值一個參數

 

f1(4,arg2=3,arg3 = 2) # 正確

 

四、動態參數 定義形式參數時,按正常模式應該是定義多少個參數就能使用多少個參數,可是可使用*來轉換參數,這樣調用函數時傳遞的實際參數就再也不有數量限制,而傳遞進的多個參數將會顯示爲元組的格式

 

 

def f3(*xx):

  print(type(xx))

  for x in xx:

    print("x= %s " % x)

 

f3("aa","bb",33,44)

 

結果

<class 'tuple'>

x=aa

x=bb

x=33

x=44

 

 

傳遞的多個參數就是一個元組

 

這種方式有幾種狀況

 

當傳遞的實際參數是一個列表,那麼傳遞進去後,會將這個列表做爲元組中的第一個元素

 

 

def f3(*xx):

  print(xx)

  print(type(xx))

  for x in xx:   

    print("x= %s " % x)

 

li=["aa","bb",33,44]

f3(li,"xx")

 

結果

(['aa', 'bb', 33, 44], 'xx')  # li的所有列表做爲參數的第一個元素,xx做爲第二個元素

<class 'tuple'> # 整個參數變爲一個列表

x=['aa', 'bb', 33, 44]          # 在執行for循環時值執行了列表被完整的輸出了

x=xx

 

 

當傳遞的實際參數自己也加了*,則會將傳遞的列表內的元素拆出轉換爲元組中的元素

 

 

 

def f3(*xx):

  print(xx)

  print(type(xx))

  for x in xx:

    print("x=%s"%x)

 

li=["aa","bb",33,44]

f3(*li,"xx")               # 傳遞的列表前有一個星號

 

結果

 

('aa', 'bb', 33, 44, 'xx')

<class 'tuple'>

x=aa

x=bb

x=33

x=44

x=xx

 

 

當傳遞一個帶星的字符串時,這個字符串裏的每個字母也會被轉化爲元組的元素

 

 

def f3(*xx):

  print(xx)

  print(type(xx))

  for x in xx:

    print("x=%s"%x)

 

 

f3(*"alix")

 

('a', 'l', 'i', 'x')

<class 'tuple'>

x=a

x=l

x=i

x=x

 

當傳遞2個*號時,傳遞的參數爲字典類型

def f3(**xx):

  print(xx)

  print(type(xx))

  for x in  xx:

    print("x= %s " % x)

 

 

f3(kk=11,aa=22)

 

輸出

 

{'aa': 22, 'kk': 11}

<class 'dict'>

x=aa

x=kk

 

 

若是傳遞的參數自身是一個字典,則須要將這個傳遞的參數前加2個星號

 

def f3(**xx):

  print(xx)

  print(type(xx))

    for x in xx:

      print("x=%s"%x)

 

ss={'aa':22,'kk':11}

 

f3(**ss)

 

 

{'aa': 22, 'kk': 11}

<class 'dict'>

x=aa

x=kk

 

 

 

五、萬能參數(*args,**kwargs):在設置形式參數時,同時制定兩種動態參數,這樣傳入的普通參數會做爲函數中元組的元素,而傳入的字典,則會被**的參數轉換爲字典

 

 

def f4(*args,**kwargs):

  print(args)

  print(kwargs)

 

f4("aa","bb","cc",kk=123,ss="bbb")

 

輸出

 

('aa', 'bb', 'cc')

{'ss': 'bbb', 'kk': 123}

 

萬能參數會自動識別不一樣類型的動態參數,同時由於字典仍是元組都容許爲空,因此即使傳遞的參數並未按照函數建立的所有順序輸入,仍然能夠建立對應的空元組或空字典

 

def f4(*args,**kwargs):

  print(args)

  print(kwargs)

 

f4(kk=123,ss="bbb") # 只傳遞字典格式

 

輸出

 

() # 元組自動被識別爲空

{'kk': 123, 'ss': 'bbb'}

 

萬能參數在設置形式參數時必須是單個星號在前,2個星號在後,也就是必須是(*args,**kwargs)

 

 

 

 

針對函數的幾點補充:

 

一、根據解釋器讀取的順序,當出現重名函數時,最後一次出現的函數將會被執行,由於以前的函數會被以後出現的函數替換加載進內存中。

 

def f1():

    retrun a+b

 

def f1():

    retrun a*b

 

a = f1(3,4)

 

最終的結果,相乘的函數被執行。

 

 

二、當調用函數時,傳遞的並非一個複製的值,而是合格參數的地址,所以當咱們傳遞了一個列表給函數時,函數對這個列表作的任何操做,都將直接做用於這個列表自己。

 

def f1(a):

    a.append(99)

 

list = [11,22,33]

 

f1(list)

 

print(list)

 

最終的結果是[11,22,33,99]

 

三、全局變量,定義在函數外的變量能夠被任何函數引用,所以稱爲全局變量。而定義在函數內的變量只能被本函數引用,所以稱爲局部變量。全局變量應該全大寫,在局部變量中若是想要更新全局變量,須要使用global,可是若是全局變量是字典或列表,則只能夠修改,不能夠從新賦值。

 

修改字符串,須要用global聲明變量

NAME = "LIUBO"

 

def f1()

    global NAME

    NAME = "ZHANGSAN"

 

f1()

 

print(NAME)

 

修改字典

 

li={"a":11}

 

def chli():

  li["b"]=22

 

chli()

 

print(li)

 

輸出

{'a': 11, 'b': 22}

 

修改列表

li=[11,22]

def chli():

  li.append(22)

 

chli()

 

print(li)

 

輸出

[11, 22, 22]

 

 

上面的例子,按正常來講函數中變動的變量僅在函數內有效,可是由於使用了global的方式宣告了這個是全局變量,所以後面對NAME的修改就會應用到全局變量中

 

 

三元運算,三目運算

 

爲真的處理  if 條件 else 爲假的處理

 

print(1)if 1==2 else print(0)

 

至關於

 

if 1 == 2:

  print(1)

else:

  print(0)

 

條件爲真 打印1 ,條件爲假打印0

 

a = 1 if 1 == 1 else 2

 

條件爲真時 a = 1 ,條件爲假時 a = 2

 

等價於

 

if 1 == 1:

    a = 1

else:

    a = 2

 

 

lambda表達式,對於簡單的函數能夠直接使用lambda表達式定義

 

 

def f1(a1,a2):

    return a1+a2

上面的函數等價於

 

f1 = lambda a1,a2: a1+a2

 

def f1(a1,a2=9)

    return a1+a2+100

能夠寫爲

f1 = lambda a1,a2=9 : a1+a2+100

 

f1(9)    #由於函數定義了默認參數,所以只須要傳遞一個參數便可

 

lambda表達式僅能使用一行定義,所以只能定義簡單函數,即函數中不能在加入其它的操做,直接返回

 

 

內置函數

 

 

 

abs() 取絕對值

n = abs(-1)

print(n)

輸出爲1

 

all() 全部爲真,才爲真

在布爾函數中表示False的內容有0,None,「」,[],{}

即空的字符串,列表,字典 元祖都是False

 

all([11,22,33]) 這樣爲真

all([11,22,「」) 這樣就爲假了

 

 

any() 有真就是真

 

 

ascii()  自動執行對象的_repr_方法

 

 

bin()  接收一個十進制數字轉爲二進制

oct() 接收一個十進制數字轉爲八進制

hex() 接收一個十進制數字轉爲十六進制

 

bool() 返回真假

 

 

bytes()

對於UTF-8編碼一個漢字佔3個字節

GBK編碼一個漢字2個字節

字符串轉換爲字節類型,bytes("要轉換的字符串",encoding="所用的編碼類型")

 

print(bytes("劉",encoding="utf-8"))

print(bytes("劉",encoding="gbk"))

 

 

 

str()

將字節轉化爲字符串

str(須要轉化的字節,encoding="須要的編碼類型")

print(str(b'\xe5\x88\x98',encoding="utf-8"))

 

 

open()

 

文件操做

 

一、打開文件

f = open("文件名","操做模式",encoding="編碼")

在打開一個文件時,這個文件裏的內容是二進制的,那麼二進制轉換爲字符串時有一個轉換動做的。

open語句會使用一個默認的編碼方式來讀取文件,更換編碼須要在open中指定

open("text.log","r",encoding="gbk")

 

在操做模式中有一個b(rb,xb,wb),這樣至關於咱們不須要python幫咱們作編碼轉換,那麼不管是咱們寫仍是讀就都須要使用二進制的數據類型傳遞。

 

也就是操做模式沒有b則是字符串類型str ,只要有b則是字節型,bytes

 

f=open("test.log","ab")

f.write(bytes("劉博",encoding="utf-8")) # 寫操做必需要加編碼

f.close()

 

文件內容(追加)

dial-peer voice 1 voip1

dial-peer voice 1 voip2

dial-peer voice 1 voip3

dial-peer voice 1 voip4

dial-peer voice 1 voip5

dial-peer voice 1 voip6

劉博

 

+符號表明操做模式可讀可寫,可是方式有所區別

 

每當open一個文件時,至關於有一個指針出如今文件中,當read()時表明文件內全部的字節都被讀了一次,這時指針也就隨之指向到文件的最後。

 

能夠經過seek(位置)方法來指定指針的位置。不管是使用b仍是不帶b的方式讀取,seek都是按照字節來制定位置,若是存在漢字,一個漢字在utf8中是3個字節,若是文件只有一個漢字,可是seek(1)這樣指針其實是指到了這個漢字的第一個字節的後面。

 

 

 

在寫入一個內容的時候,python會默認從指針的位置向後替換 原有的字符

 

f=open("test.log","r+")

f.seek(10)    #將指針指向第10個位置

f.write("ssss")

f.close()

 

結果

 

dial-peer sssse 1 voip1      #能夠看到從第十個字符開始原來的voice前4個字母被替換爲s了

dial-peer voice 1 voip2

dial-peer voice 1 voip3

dial-peer voice 1 voip4

dial-peer voice 1 voip5

dial-peer voice 1 voip6

劉博

 

 

獲取當前指針的位置tell(),tell方法指定的位置永遠是字節

f=open("test.log","r+")

f.seek(10)

a=f.tell()

f.close()

print(a)

打印

10

 

 

r+,a+,w+三種都是可讀可寫,可是隻有r+能夠指定指定指針的位置寫入,a+是追加不管怎麼指定,寫入的都只能從最後追加,w+則會清空源文件

 

所以寫入方式中r+使用的最普遍

 

 

 

操做模式:

 

 

r

只讀

w

只寫(先清空源文件,後寫入)

x

python3.0新增:若是文件存在時則報錯,若是不存在建立並寫內容

a

追加

r+

可讀可寫,最經常使用

a+

可讀可寫,從最後寫

w+

可讀可寫,可是先清空源文件

 

 

 

二、操做文件

經過源代碼查看功能

 

read(),若是無參數,則讀所有,若是有參數,打開方式若是有b按字節讀取,無b按字符讀取。

seek(),按字節指定指針位置

tell(),按字節獲取當前指針位置

 

write(),寫數據,若是打開方式中有b按字節,無b按字符寫

 

close()

 

fileno() 文件描述符,即文件的數字表達方式

 

flush() 強刷,將內容強刷到硬盤上,當咱們打開了一個文件,寫入一個內容,以後作了一個操做暫停在這裏(好比input要求用戶輸入,但用戶沒有輸入)此時文件沒有關閉。默認狀況下這個內容是不會寫到文件裏的。此時能夠經過flush方法在文件關閉前強制將內容寫到文件中。

 

 

readable() 判斷是否可讀

 

seekable() 判斷是否能夠移動指針

 

readline() 僅讀取一行,實際是執行完這句後,指針指向第二行開始,因此在此執行就會讀取第二行

 

writeable() 判斷是否可寫

 

truncate()  會將指針後面的內容所有清空

 

for循環open以後的文件對象,循環每一行

    f = open("test.log","r")

    for line in f:

        print(line)

 

 

 

 

 

 

三、關閉文件

f.close()

 

 

 

 

使用with的文件操做

 

 

with open("文件名") as f:

    pass

上面的with代碼執行完,文件自動關閉,不須要特地寫close

 

python 2.7以後with支持打開多個文件

 

with open("1.log","r",encoding="utf-8") as f1, open("2.log","w",encoding="utf-8") as f2:

    time = 0

    for line in f1:

        time += 1

        if time <=10:

            f2.write(line)

        else:

            break

上面的代碼使用with,只讀打開1.log,只寫打開2.log,而後將1.log中前10行數據寫入2.log中

 

 

上面說打在python中寫入數據是從指針位置開始替換後面的,那麼當咱們要修改文件中不等長的數據(例如將alex替換爲st)就會破壞原有的數據。

 

而open讀取的數據默認是字符串的類型,所以咱們可使用字符串的操做。str.replace("源字符串","替換字符串")的方式替換。

 

逐行處理就是

 

with open("1.log","r",encoding="utf-8") as f1, open("2.log","w",encoding="utf-8") as f2:

     for line in f1:

        new_str = line.replace("alex","st")

        f2.write(new_str)

相關文章
相關標籤/搜索