Python成長之路 基礎篇3

基礎篇3

一、集合

二、文件的操做

三、字符編碼轉換

四、函數

五、局部變量與全局變量

六、遞歸

七、高階函數

 

1、集合

集合是一個無序的、不重複元素集合,其中的元素是不可變的。python

基本的功能:

去重:列表和元組中有相同的元素能夠轉換爲集合去重正則表達式

關係測試:集合的交集、並集、差集等相關關係的測試express

 

集合的建立及一些基本操做:

集合的建立app

 1 >>> s = set('school')                  #建立集合    
 2 >>> print(s)
 3 {'l', 'o', 'c', 'h', 's'}
 4 >>> s2 = {'s', 'c', 'h', 'o', 'o', 'l'} #等同於 set({'s', 'c', 'h', 'o', 'o', 'l'})
 5 >>> print(s2)
 6 {'l', 'o', 'c', 'h', 's'}
 7 >>> s3 = set(['s', 'c', 'h', 'o', 'o', 'l'])
 8 >>> print(s3)
 9 {'l', 'o', 'c', 'h', 's'}
10 #上面都是使用集合的工廠方法se()來建立集合
View Code

在上面注意了建立一個空的集合時只能使用s=set()建立,不能使用s={}建立。ide

 

查看集合中的成員及判斷是否爲集合中成員函數

 1 >>> s = set(['s', 'c', 'h', 'o', 'o', 'l'])
 2 >>> 's' in s     #判斷元素‘s’ 是集合s的成員,是返回True、不然返回False
 3 True
 4 >>> 's' not in s   #判斷元素‘s’ 不是集合s的成員,不是返回True,不然反之
 5 False
 6 >>> for i in s:
 7 ...     print(i)
 8 ...     
 9 l
10 o
11 c
12 h
13 s
14 #上面使用遍歷的方法查看集合中的成員
View Code

 

集合的增刪操做測試

 1 >>> s = set(['s', 'c', 'h', 'o', 'o', 'l'])
 2 >>> s.add('l')
 3 >>> print(s)
 4 {'s', 'h', 'o', 'l', 'c'}
 5 >>> s.add('w')
 6 >>> print(s)
 7 {'l', 'w', 'c', 's', 'h', 'o'}
 8 #當添加的元素集合中有的時候,因爲集合的去重特性因此集合沒有變化
 9 #只有添加的元素在集合中不存在時,集合纔會發生變化
10 >>> s = set(['s', 'c', 'h', 'o', 'o', 'l'])
11 >>> s.remove('w')          #刪除的集合不存在會報錯
12 Traceback (most recent call last):
13   File "<input>", line 1, in <module>
14 KeyError: 'w'
15 >>> s.remove('l')
16 >>> print(s)
17 {'s', 'h', 'o', 'c'}
18 >>> s.pop()                   #隨機在集合中刪除元素
19 's'
20 >>> s.discard('w') #刪除的元素不在集合中,不會報錯通常使用該方法
21                              #刪除元素
22 >>> print(s)
23 {'h', 'o', 'c'}
24 >>> s.discard('c')            
25 >>> print(s)
26 {'h', 'o'}
View Code

 

集合的並集、交集、合集、對稱差集及其餘操做編碼

 1 >>> s = set(['q', 2, 'w', 888, 666])
 2 >>> s2 = set(['e', 1, 'r', 888, 999 ])
 3 >>> s.union(s2) 
 4 {1, 2, 999, 'w', 'r', 888, 666, 'e', 'q'}
 5 >>> s | s2
 6 {'q', 2, 'w', 1, 999, 'r', 'e', 888, 666}
 7 #取並集,返回的是集合s和s2中全部的去掉重複的元素的集合
 8 #s和s2自己沒變化
 9 >>> s.intersection(s2)
10 {888}
11 >>> s & s2
12 {888}
13 #取交集,返回的是集合s和s2中相同元素的集合
14 #s和s2自己沒變化
15 >>> s.intersection_update(s2)
16 >>> print(s)
17 {888}
18 >>> print(s2)
19 {888, 1, 'e', 'r', 999}
20 #更新集合s,保留2個集合相同的元素
21 
22 
23 
24 
25 >>> s = set(['q', 2, 'w', 888, 666])
26 >>> s2 = set(['e', 1, 'r', 888, 999 ])
27 >>> s.difference(s2)
28 {'w', 2, 'q', 666}
29 >>> s - s2
30 {'q', 2, 'w', 666}
31 #取差集,返回的是集合s中有的元素,s2中沒有的元素的集合
32 #s和s2自己沒變化
33 >>> s.difference_update(s2)
34 >>> print(s)
35 {'w', 2, 'q', 666}
36 >>> print(s2)
37 {888, 1, 'e', 'r', 999}
38 #更新集合s,在集合s中去掉2個集合相同的元素
39 
40 
41 >>> s = set(['q', 2, 'w', 888, 666])
42 >>> s2 = set(['e', 1, 'r', 888, 999 ])
43 >>> s.symmetric_difference(s2)
44 {1, 2, 999, 'w', 'r', 666, 'e', 'q'}
45 >>> s ^ s2
46 {1, 'q', 2, 'w', 999, 'r', 'e', 666}
47 #對稱差集,返回的集合中的元素在s和s2中,但不一樣時在這2個集合中
48 #s和s2自己沒變化
49 >>> s.symmetric_difference_update(s2)
50 >>> print(s)
51 {1, 2, 999, 'w', 'r', 666, 'e', 'q'}
52 >>> print(s2)
53 {888, 1, 'e', 'r', 999}
54 #這個就是更新集合s是裏面的元素在s和s2中,但不一樣時在這2個集合中
55 #沒有返回值,s集合發生變化,s2集合沒有發生變化
56 
57 
58 
59 >>> s = set([2, 3, 4, 99])
60 >>> s2 = set([2, 3, 4])
61 >>> s3 = set([888,999])
62 >>> s.issuperset(s2)
63 True
64 #檢查s是否是s2的父集,是返回True,不然返回Falsh
65 >>> s2.issubset(s)
66 True
67 #檢查s2是否是s的子集,是返回True,不然返回Falsh
68 >>> s2.isdisjoint(s)
69 False
70 #檢查集合s2和集合s有沒有相交的沒有則返回True,不然返回Falsh
71 >>> s.isdisjoint(s3)
72 True
73 #檢查集合s和集合s有沒有相交的沒有則返回True,不然返回Falsh
74 #上面主要檢測2個集合有沒有同樣的元素有則返回True,不然返回Falsh
75 
76 >>>s = set(['q', 2, 'w', 888, 666])
77 >>>s3 = s.copy()
78 >>> print(s3)
79 {'w', 2, 'q', 666}
80 >>> s3.add('d')
81 >>> print(s)
82 {'w', 2, 'q', 666}
83 >>> print(s3)
84 {'w', 2, 'q', 'd', 666}
85 #這個屬於淺copy
86 >>> s.clear()
87 >>> s
88 set()
89 #清空集合,使之變爲一個空集合
View Code

上面只介紹了交集、並集、合集和對稱集介紹了使用運算符的使用方法。其餘的也可使用運算符的方法,可是我的覺的記得比較繁瑣,只記住這幾個比較好點。要是想知道其餘的使用符號怎麼表示能夠去本身在網上查查。spa

 

2、文件的操做

文件的打開有兩種方式:操作系統

一、f = open(file_name,[mode])

二、with open(file_name,[mode]) as f:

第二種方式相對於第一種方式比較好點。第二種方式造成上下文在執行完這段代碼時會自動關閉文件,不像第一種須要主動用f.close()來關閉文件。同時再打開不存在的文件時報錯,使用第一種方法在使用try...finally解決報錯問題代碼變得複雜,而是用第二種方法是會使代碼變的更簡潔。

打開文件的方式

這個方式指的是打開文件的模式也就是上面的mode

r :  只讀模式打開文件,咱們只能進行讀操做不能進行其餘的操做。若是文件不存在會報錯

 

w:   以寫的方式打開文件,文件若存在,首先要清空文件,而後從新建立。若文件不錯在則建立該文件

 

a:    以追加的方式打開,文件不支持讀的操做,只能在文件末尾追加。文件不存在就建立該文件。

 

 r+:  以讀寫的方式打開該文件,該方式使用的時候若是使用open()方式後沒有進行任何的讀的操做那麼咱們寫入信息的時候,會從文件的頂部寫入,寫入一個字節就會覆蓋一個字節。若是進行了讀的操做的時候,那麼咱們寫入信息的時候,寫入的信息就會追加到文件的末尾。

下面這個代碼表示再打開文件和關閉文件的這個過程當中,對文件不進行任何讀操做時,向文件寫入字符串時寫入的方式。

下面的操做是對文件打開了2次第一次是爲了看裏面的內容

with open('zhetian.txt', 'r+') as f:
    print(f.read())
print('----------------')
with open('zhetian.txt', 'r+') as f:
    f.write('ok')
    f.seek(0)
    print(f.read())

上面的運行結果以下,能夠看出在不進行讀的操做是,向裏面寫一個字符就覆蓋源文件的一個字符。

hello world
hello world
----------------
okllo world
hello world

 

下面驗證了在一次打開和關閉的狀況下咱們先對文件進行了讀操做,咱們向文件中寫入相應的字符的操做。

with open('zhetian.txt', 'r+') as f:
    print(f.read())
    f.write('ok')
    f.seek(0)
    print(f.read())

 咱們從結果能夠看見咱們寫入的字符會默認添加在文件的末端

hello world
hello world
hello world
hello worldok

只要咱們對文件進行了讀這個操做那麼,無論讀到那個位置咱們添加字符的位置都會在文件的末端,與光標所在的位置沒什麼影響。

當咱們寫完時,讀的時候會從寫完的位置開始讀(注:當咱們向文件中寫入字符時咱們的光標就會在寫入字符的位置)

光標:當咱們打開文件的時候咱們的光標通常會默認會在文件的頂部,當咱們進行讀的操做時,咱們讀到那裏咱們的光標通常會移到某個位置,一樣咱們寫到那個位置咱們的光標也會在相應的位置。若是是追加模式的話光標在文件的末端。

 

w+:  以寫讀的方式打開文件,若是文件不存在,則建立。若存在,則清空裏面內容。

a+: 該追加方式能夠讀,裏面的光標位於文件的末端,因此要想讀取裏面的內容則使用seek()方法移動光標。

同時打開文件也有rb、wb、ab、rb+、wb+、ab+,這個與上面的同樣的方式同樣不過只是一二進制的方式打開文件。

文件的一些方法和屬性

 1 file.close()
 2 #關閉文件,這個方法只在 f = open()的方式下才使用,
 3 #而with open() as f:該方式自帶關閉文件
 4 
 5 file.flush()
 6 #刷新文件內部緩衝,直接把內部緩衝區的數據當即寫入文件
 7 #而不是別動等待緩衝區寫入
 8 
 9 file.seek(offset,whence)
10 #移動文件中光標的位置
11 #offcset指的是光標移動多少個字節,記住這個是字節不是字符,如中文utf-8表示的是3個字節
12 #whence能夠有多個選項,0:從文件頭 。1:從當前位置 。2:從文件尾部不過默認的爲0
13 #file.seek(0)這個0表明的是whence因此offset默認爲0
14 
15 file.fileno()
16 #方法返回一個整型的文件描述符(file descriptor FD 整型)
17 #可用於底層操做系統的 I/O 操做。
18 
19 file.read(size)
20 #在文件中讀取指定字符數,若是沒有或者是負數默認爲讀取所有
21 #讀取完成後光標在你讀取的位置
22 
23 file.readline(size) 
24 #讀取整行,包過'\n'字符。光標移動.取出來的是字符串,
25 #size不爲零或者負數,就取該行指定字節
26 #光標位於行尾
27 
28 file.readlines(size)
29 #讀取全部行並返回列表。其中包過'\n'字符
30 
31 file.isatty()
32 #若是文件鏈接到一個終端設備返回 True,不然返回 False。
33 
34 file.tell()
35 #報告當前文件中光標的位置
36 
37 file.name
38 #這是屬性不是方法
39 #顯示當前文件的文件名
40 
41 file.truncate(size)
42 #用於從文件的首行首字符開始截斷,
43 #size表示的是字節,也就是說截取size字節。後面的刪掉這個包過換行符
44 
45 file.write(str)
46 #將字符串寫入文件,沒有返回值
47 
48 file.writelines(sequence)
49 #向文件中寫入一序列的字符串。
50 #這一序列字符串能夠是由迭代對象產生的,如一個字符串列表。
51 #換行須要制定換行符 \n。
52 
53 file.closed
54 #這是屬性用來判斷文件是否關閉
55 
56 file.mode
57 #這是屬性,文件打開的模式
View Code

文件的內容查找和替換

 1 data = ''
 2 
 3 with open('test.txt', 'r') as f:
 4     for line in f.readlines():
 5         if(line.find('Server') == 0):
 6             line = 'Server=%s' % ('192.168.1.1') + '\n'
 7 
 8         data += line
 9 
10 with open('test.txt', 'w') as f:
11     f.writelines(data)
12 #這是修改某一行的信息
13 #上面的方法是查找文件中的某行在修改改行的數據不過若是大概的文件裏#面的內存容量過大可能致使卡頓現象,因此建議在小容量的文件使用。
14 #若是文件太大,這種方法使用內存使用量會不少浪得內存,使得運行很卡
15 
16 with open('zhetian.txt', 'r') as f:
17     with open('zhetian1.txt', 'w') as f1:
18         for line in f:
19             if(line.find('Server') == 0):
20                 line = 'Server=%s' % ('192.168.1.1') + '\n'
21                 f1.write(line)
22             else:
23                 f1.write(line)
24 with open('zhetian.txt', 'w') as f:
25     with open('zhetian1.txt', 'r') as f1:
26         for line1 in f1:
27             f.write(line1)
28 #這個方法是一行一行的往內存中讀一行而後把這行寫入到新的文件中,
29 #這樣內存中始終只有一行,而後把新的文件一行一行寫入原來文件中
30 #由於python3不支持原地修改而後存儲因此要想高效就是用上面的方法
31 
32 with open('test.txt','r') as fopen:
33     for line in fopen:
34         if re.search('world',line):
35             line=re.sub('world','hello',line)
36             w_str+=line
37         else:
38             w_str+=line
39 print(w_str)
40 with open('test.txt','w') as wopen:
41     wopen.write(w_str)
42 #這個是查找文件中的某個單詞進行替換。
43 #這個一樣若是文件過大也會出現上面狀況
44 
45 import re
46 with open('zhetian.txt','r') as fopen:
47     with open('zhetian1.txt', 'w') as f1:
48         for line in fopen:
49             if re.search('world',line):
50                 line=re.sub('world','hello',line)
51                 f1.write(line)
52             else:
53                 f1.write(line)
54 with open('zhetian.txt','w') as wopen:
55     with open('zhetian1.txt', 'r') as f1:
56         for line1 in f1:
57             wopen.write(line1)
58 #這種方法和上面第二種方法同樣這樣會寫一行到內存中而後就刪除,
59 #內存中始終保持只有一行,節約內存空間這樣在打開大的文件可使用
60 #上面使用了正則表達式
61 #上面全部的文件使用的是相對位置裏面能夠放絕對位置,建議寫絕對位置
View Code

從上面的列子咱們能夠知道當咱們的文件太多的時候使用readlines()方法這樣會佔用大量內存。

因此在查找的時候咱們可使用for i in f:這種方式來讀取裏面的內容。

注意:咱們上面可使用os模塊把舊文件刪除,新文件從新命名如:

os.remove('old_file')

os.rename('new_file','old_file')

若是打開多個文件咱們能夠用如下方式:

with open('test1.txt', 'w') as f1 ,\
open('test2.txt', 'w') as f2:
    pass

with open('test1.txt', 'w') as f1:
    with open('test2.txt', 'w') as f2:
        pass

  

3、字符編碼的轉換

 關於字符編碼的轉換的問題我我的推薦到網上看看各位大神寫的看法,在這裏我只給你們提供一個字符編碼轉換的圖,這個圖也是從大神們那裏copy過來的

經過別大神們的看法和牢記住這幅圖我的感受關於編碼的應該沒問題了,這個仍是要看本身多多得琢磨琢磨。

4、函數

函數是組織好的、可重複使用的、用來實現單1、或相關聯功能的代碼段。

函數可以提升應用的模塊性,和代碼的重複利用率。咱們已知Python提供了許多內建函數,好比print()。

咱們一樣也開始本身建立函數,這種函數叫用戶自定義函數。

一、函數的定義

  函數代碼塊以def關鍵詞開頭,後接函數標識符和圓括號()。

  任何傳入參數和自變量必須放在圓括號中間,圓括號之間能夠用於定義參數。

  函數的第一行語句能夠選擇性的使用文檔字符串用來存放函數說明。

  函數的內容以冒號起始,而且縮進。

  renturn[表達式]結束函數,選擇性的返回一個值給調用。不帶表達式的renturn至關於返回None。

二、函數的一些特性

  1.減小代碼的重複性

  2.使程序變的可擴展

  3.使程序變的易維護

函數的基本格式爲

def func_name(arg_list):

  """文檔字符串"""

  函數體

  return [expression]  

 

注:上面的arg_list、文檔字符串和return是可選的。

func_name:函數名

return:返回值

 

下面是一個簡單的函數:

def func():
    print('Hello function')

func()  #表示函數的調用


#上面運行的輸出的結果:
Hello function

  

函數中帶有參數

關鍵字參數和位置參數

def func(x,y):
    print('Your height is %s cm'% x)
    print('Your weight is %s kg'% y)

func(170,55)  #調用的時候,實參和上面的形參是一一對應的。這種情形下的實參爲位置參數
print("--------------------")
func(x=175,y=55) # func(y=55, x=175)和前面的等同,主要看前面的關鍵字和形參對應就好。
#這種的的參數咱們叫作關鍵字參數,關鍵字參數不須要注意位置。
#當關鍵字參數和位置參數一塊兒用的時候,必定要記住位置參數必定要在前面。
#同時位置參數對應的形參關鍵字不可以再次對應,要不程序回報錯。
#關鍵字參數和位置參數必需要和上面的形參數目同樣,不能少也不能多
#func(175,y=55)這樣能夠、func(55,x=175)這樣會報錯說同一個參數只能賦值一次
#func(x=175,55)這樣寫也會報錯
#記住傳參的時候,無論使用位置參數仍是關鍵字參數,都要遵照上面的要求。

#上面運行屏幕輸出的結果 Your height is 170 cm Your weight is 55 kg -------------------- Your height is 175 cm Your weight is 55 kg

 默認參數

def func(name, age, salary=3000):
    print('Your name is %s '% name)
    print('Your age is %s '% age)
    print('Your salary is %s' % salary)

func(name='xiaoming',age='man')
print('---------------------')
func(name='xiaoming',age='man',salary=5000)
#上面運行的結果
Your name is xiaoming 
Your age is man 
Your salary is 3000
---------------------
Your name is xiaoming 
Your age is man 
Your salary is 5000
#上面能夠看出咱們的有默認參數時,在調用函數時,若是沒有傳遞參數,則使用默認參數。
#若是默認參數傳遞了參數,就以傳遞的參數爲準
#同時注意寫函數是默認參數都放在右邊要不就會報錯,
#若是裏面有不定長參數的時候,由於不定長參數能夠在任何位置,
#因此有可能默認參數在不定長參數前面

  

不定長參數*args

def func(name,age,salary=3000,*args):
    print('Your name is %s '% name)
    print('Your age is %s '% age)
    print('Your salary is {}'.format( salary))
    print(args)

func('xiaoming','man',5000,'music',)
#運行的結果
Your name is xiaoming 
Your age is man 
Your salary is 5000
('music',)
#因爲不定長參數*args傳參的時候傳的是位置參數,且位置參數必需要在關鍵字參數前面
#因此咱們使用*args時,若是裏面使用位置參數和關鍵字參數那麼能夠把*args放在前面
#如:
def func(*args,name,age,salary=3000):
    print('Your name is %s '% name)
    print('Your age is %s '% age)
    print('Your salary is {}'.format( salary))
    print(args)

func('music',name='xiaoming',age='man',salary=5000)
#若是把不定長參數*args放在後面的話,前面就不能使用關鍵字參數來傳參
#同時*args傳進去的參數會以元組的方式出現

  

不定長參數**kwargs

#**kwargs傳參使用的是關鍵字參數,且傳入參數會以字典(dict)的形式出現
def func(name,age,**kwargs):#**kwargs放在後面
    print('Your name is %s '% name)
    print('Your age is %s '% age)
    print(kwargs)

func(name='xiaoming',age='man',salary=6000,address='beijing')

#上面運行的結果
Your name is xiaoming 
Your age is man 
{'address': 'beijing', 'salary': 6000}

#因爲不定長參數**kwargs傳參的時候使用的是關鍵字傳參。
#因此不定長參數**kwargs因此必定要把它放在後面。

可更改與不可更改對象

傳遞不可變對象

def func(a):
    a = 100

b = 50
func(b)
print(b) #結果是50

  從上面的結果中能夠看出當咱們傳遞一個不可變的對象的時候,咱們在函數內部修改該對象的時候到外面的時候該對想仍是沒有改變,上面的實列中咱們能夠看到先把b指向了內存中的50的位置,當咱們傳遞給func()函數的時候是把50的位置傳遞給了函數中的a,而後a從新給它賦值,指向內存中100的位置,這樣咱們b指向內存中的位置其實是沒有改變的,

傳遞可變對象

def func(a):
    a.append(5)
    print('a',a)

b = [1,3,6]
func(b)
print('b',b)
#結果爲
#a [1, 3, 6, 5]
#b [1, 3, 6, 5]

  從上面的列子中咱們能夠看出當咱們傳入可變對象的時候,在函數裏面修改該可變對象,咱們外面的對象也會被改變。咱們能夠認爲b指向內存地址中可變對象的位置把把它,調用到函數中時,a也指向該地址,當咱們修改該裏面的內容的時候,咱們的內存地址的位置沒有改面改變的只是裏面的內容,因此b的內容也會被改變。由於a、b指向內存中的地址都是同樣的。

不可變對象指的是字符串、元組、整數等、咱們在傳遞他們的時候該變量名指向的內存地址沒有改變,只是把它指向的內存地址給了函數裏面,當函數的變量名指向內存中的地址發生改變的時候,外部的變量名沒有受到影響。

可變對象包含了字典(dict)、列表(list)。在函數內部發生改變,外部也會發生變化

 

函數的返回值(return)

在函數中return[表達式]在函數裏面表示退出該函數,向調用該函數的返回一個表達式。

當函數中沒有return時,返回的是一個None。

當函數中return返回一個表達式時,返回的就是該表達式的值。

當函數中return返回多個表達式時,返回多個值時,並將多個值放在元組中。

在調用該函數的時候,在函數中return如下的代碼將不會執行。

def func(a):
    c = a + 20
    return c
    print('a',a)

b = 10
x=func(b)
print('x',x)#結果爲  x 30

def func(a):
    c = a + 20
    return c,a
    print('a',a)

b = 10
x=func(b)
print('x',x) #結果爲 x (30, 10)

  函數的調用,在調用函數的時候必定要記住,咱們的調用必定要在該函數以後。只要咱們調用的函數裏面還有其餘的函數,那麼咱們調用的時候也要把其它的函數寫在這個調用的前面,要不程序會報錯的。

匿名函數

使用lambda表達式來建立匿名函數。

lambda表達式的描述

  lambda只是一個表達式,比函數def簡單的多

  lambda主體就是一個表達式,不像def有一個代碼塊,只能在lambda表達式中封裝有限的邏輯語句。

  lambda函數擁有本身的名字空間,且不能訪問自有參數列表以外或全局名字空間裏的參數

  lambda函數雖然只有一行,可是卻不一樣於C或C++的內聯函數,後者目的是調用小函數時,

  不佔用棧內存從而增長運行速度。

lambda函數的格式

  lambda[arg1[,arg2...[,argn]]]]:expression

lambda函數咱們能夠直接使用也能夠把它賦值一個函數名在調用

lambda函數直接使用

print((lambda x:x**2)(4))#結果是16  把(4)中的4賦值給x,即x=4

#記住直接調用的時候,須要傳參時必定要用括號把lambda函數括起來。

  給lambda函數一個函數名

#向lambda函數裏面傳遞一個參數
func = lambda x:x**2

print(func(4))#結果是16


#向lambda函數裏面傳遞多個參數
func2 = lambda x,y,z=4:(x+y)*z

print(func2(x=2,y=2))       #結果是16  

print(func2(x=2,y=2,z=5))#結果是20
    
#這裏面傳參的時候,也就是與def函數傳參類似。

  

5、局部變量與全局變量

當咱們在函數內聲明變量的時候,它與咱們函數外面具備相同名稱的其餘變量沒有任何關係,

相對函數來講函數裏面的的變量名爲局部變量,這個變量只在這個函數裏面起做用,

無論函數外有沒有相同的變量名,而函數裏面的變量(局部變量)做用域就是這個函數塊,

只在這個函數裏面起做用,對函數外面的不起做用。

x = 100  #這個x爲全局變量
def func(a):
    print('a is',a)
    x = 10   #這個x就是局部變量
    print('x is', x)

func(5)

print('x is ',x)
#運行的結果
x is 5
x is 10
x is  100
#當函數裏面的變量名和函數外有相同的變量名時,在函數裏面調用該變量的時候它會調用函數裏面的變量。
#也就是說當咱們在函數裏面調用函數的時候,它會檢查函數裏面有沒有該變量有的話就調用它,
#沒有的話它就會調用函數外面的變量,函數裏面的變量爲局部變量。 #注意當函數裏面和外面有相同的變量,若是咱們在函數裏面調用該變量的時候,
#調用的位置在函數裏面聲明該變量以前程序會報錯說。
#局部變量只在這個函數模塊起做用除了這個模塊這個變量就沒有效果了。
x = 100
def func():
print('x',x)
   x=50
func()
#運行上面的時候,程序報錯,告訴咱們局部變量咱們在賦值前引用致使的錯誤。

要想在函數裏面咱們賦值的變量爲全局變量只須要在賦值的時候在前面聲明一下就能夠了
def func():
global x
x = 10

func()
print(x)# 結果爲 10
#記住要想這個全局變量生效那麼必定要調用該函數,不然這個變量將會沒有效果。

  

6、遞歸

遞歸函數就是一個函數內部調用函數自身,這個函數就叫遞歸函數。

遞歸特性:

  必需要有一個明確的結束條件

  每次進入更深一層遞歸時,問題的規模相比上一次遞歸都應有所減小

  遞歸效率不高,遞歸層次過多會致使棧溢出

遞歸函數不像while可以無限遞歸,在網上查了一下有的人說能夠遞歸999次有的人說能夠遞歸1000次。

這不是重點,重點是Python設置這種機制是用來防止無限遞歸形成Python溢出,這個最大遞歸次數咱們能夠本身調整的。

#使用遞歸函數計算l累加
def accum(n):
    if n==1:
        return 1
    return n+accum(n-1)

print(accum(3))#結果是6

  

7、高階函數

高階函數:

  變量能夠指向函數。

  函數的參數能夠接收變量

  一個函數能夠接收另外一個函數做爲參數

def add(a,b,f):
    return f(a)+f(b)

print(add(-4,25,abs))#結果是29

#上面就是把a的絕對值和b的絕對值相加,由於涉及到絕對值因此咱們引入絕對值的函數abs
#這個就是符合高階函數要求,因此它是高階函數。

  

本人屬於小白級別的上面寫的若有錯誤歡迎指正和交流。

相關文章
相關標籤/搜索