1. 程式人生 > >python中的關鍵字---2(函式基礎類)

python中的關鍵字---2(函式基礎類)

函式基礎

定義函式:   def 函式名():
縮排 函式體(程式碼塊)


呼叫函式: 函式名 + () 小括號


執行順序: def func(): 1
print('這大佬黑') 3
func()呼叫 2

函式的返回值:
def func(): 1
print('這大佬黑') 3
return '今晚不濺不散'
func()呼叫 2

返回一個引數的時候是它本身,返回多個就是元組形式顯示
當函式體執行到return的時候就結束函式
不寫return的時候 預設返回None 寫了return不寫返回值的時候 返回的也是None


函式的引數:

引數:

形參 : 在函式定義的時候括號裡的變數就是咱們的形參

位置引數:

按照實參的位置對應把值賦值給形參中變數

預設引數(關鍵字引數):

在函式定義的時候,直接給變數賦值
預設引數不傳參是否可以???? 可以
預設引數可以傳值嗎???? 可以 將預設引數的值覆蓋

混合引數:

位置引數在預設引數前面
例如:
def f(a,b,c = 8):
pass

實參 : 在函式呼叫的時候括號裡放入的值就是實參

位置引數:

f(1,2,3)

預設引數(關鍵字引數):

f(a=1,b=2,c=3)

混合引數:

f(1,2,c=3)

傳參: 將實參傳遞給形參的過程

三元運算:

a if a>b else b
結果 條件 結果
結果 如果條件成立使用前面的 否則就使用後邊的

函式進階
1. 函式的引數:

動態:

動態位置引數 *args

動態關鍵字引數 **kwargs

位置 > 動態位置引數 > 預設(關鍵字)引數 > 動態關鍵字引數


2. 名稱空間:

區域性名稱空間
全域性名稱空間
內建名稱空間


載入順序:

內建 > 全域性 > 區域性

取值順序:

區域性 > 全域性 > 內建

作用域:

全域性作用域:

內建 + 全域性

區域性作用域:

函式區域性


# print(globals()) # 檢視全域性作用域中的變數和函式名
# print(locals()) # 檢視區域性作用域中的變數和函式名


3. 函式的巢狀:

def f():
print(11)
def f1():
print(22)
def f2():
print(33) **********重要
f2()

f1()
f()


4. 函式的註釋:

def func():
# '''
# 這是列印的函式
# :param a: 沒啥用1
# :param b: 沒啥用1
# :param c: 沒啥用1
# :param d: 沒啥用1
# :return: 返回的None
# '''
# print(a,b,c,d)

5. global|

# print(id(lst))
# def func():
# # a = 15 # 在函式的區域性中
# # global se #
# lst[0] = 11
# # print(a) # 使用的是區域性
# func()
# print(lst)
# print(id(lst))

# 可變資料型別在函式中可以直接操作,不可變資料型別才需要使用global


# a = 10
# def f():
# a = 1 # a = 2
# def f1():
# # a = 4 # a = 2
# def f2():
# # nonlocal a
# # a = 2
# print(a) # 2
# f2()
# print(a) # 2
# f1()
# print(a) # 2
# f()

# nonlocal 改變最近的父級變數, 如果上級沒有能夠改變的就繼續向上走,直到最外層函式就停止了.


##### 函式: 將一個需求封裝後呼叫,優點:除去重複程式碼.

閉包
# 閉包: 內部函式使用了外部函式的變數,內部函式就是一個閉包
# def outer():
# a = 1
# b = '123'
# c = [1,2,3]
# def inner():
# print(1234)
# print(inner.__closure__) # inner不是一個閉包
# outer()
#
# def outer():
# a = 1
# b = '123'
# c = [1,2,3]
# def inner():
# print(a,b,c)
# print(inner.__closure__) # inner是一個閉包
# outer()

# def outer(a):
# def inner():
# print(a)
# print(inner.__closure__) # inner是一個閉包

# def outer(url):
# def inner():
# print(a)
# print(inner.__closure__)

# from urllib import request # 別人寫好了python程式碼的檔案
# ret = request.urlopen('http://www.cnblogs.com/Eva-J/articles/7213953.html')
# print(ret.read().decode('utf-8'))

# 訪問一個網頁
# 會被頻繁的訪問
# import time
# from urllib import request
# def func2(url):
# ret = request.urlopen(url)
# content = ret.read().decode('utf-8')
# return content
#
# start = time.time()
# for i in range(10):
# func2('http://www.cnblogs.com/Eva-J/articles/7213953.html')
# print(time.time() - start)
#
# from urllib import request # 匯入別人寫好的python程式碼,urllib是專門負責訪問url的
# def func(url):
# ret = request.urlopen(url) # 利用urlopen函式開啟一個url得到結果ret
# content = ret.read().decode('utf-8') #使用ret的read方法得到bytes型別的網頁原始碼,然後轉碼成str
# def inner():
# return content
# return inner
#
# ret = func('http://www.cnblogs.com/Eva-J/articles/7213953.html')
# # 相當於將url對應的內容存在了url中,每一次呼叫ret就是獲取內容的過程
# for i in range(10):
# ret()
# print(time.time() - start)

# 閉包的應用
# 快取
# 裝飾器


# def func(*args):
# sum_num = 0
# for num in args:
# sum_num += num
# def inner():
# return sum_num
# return inner
#
# inner = func(1,2,3,4)
# inner()

迭代器
# 什麼是迭代器?
# l = [1,2,3,4]
# res = l.__iter__()
# print(res)
# list_iterator iterator迭代器
# dir(l)
# print(dir(res))
# res中 但是不在l中的所有方法
# print(set(dir(res))-set(dir(l)))
# {'__next__', '__setstate__', '__length_hint__'}
# 迭代器中特有的方法,l中沒有
# print(res.__length_hint__()) # 迭代器中有多少個元素
# for i in res:
# print(i)
# res.__setstate__(2) # 控制迭代器從哪兒開始迭代
# for i in res:
# print(i)
# print(res.__next__()) # 從迭代器中取下一個值
# print(res.__next__())
# print(res.__next__())
# print(res.__next__())
# print(res.__next__())
#
# for迴圈一個列表的時候必須用的
# __next__取下一個值
#
# 迭代器協議 : 含有__next__和__iter__方法的變數/值都是迭代器
#
# 迭代器的特點:
# 具有next和iter方法
# 通過一個next多次執行就可以獲得所有這個容器中的值
# 迭代器中的值只能取一次
# 不取的時候值不出現
#
# for迴圈取值
# for迴圈內部的機制就是迭代器取值的機制
# 在for迴圈執行的過程中 : 先把可迭代的變成一個迭代器,然後再從中一個一個的取值
#
# range生成的就是一個迭代器,建立這個迭代器並不會真的把迭代器中的所有資料一次性生成
# 什麼時候生成呢? 只有通過next取值的時候才會生成
# 記住你要多少個值 ,當前該給你什麼,並且記住我下一個該給你什麼,下一個和當前這個數的關係
#
# f檔案控制代碼
# f記住 當前讀到哪個位置了
#
# a = list(range(1000000000))
# print(a)
#
# 迭代器的作用就是節省記憶體,for迴圈就是利用了迭代器節省記憶體的特點來對python當中的變數來進行操作的

生成器
# python語言自帶的
# 生成器 : 程式設計師通過簡單的函式就可以實現的
# def func():
# print('hello')
# yield 1
#
# g = func() # 呼叫"生成器函式"
# print(g) # g generator(生成器)
# 呼叫就不會執行這個函式,而是返回一個生成器
# print(dir(g)) # g是一個迭代器
# 所有的生成器都是迭代器
#
# a = g.__next__()
# print(a)
#
# def func():
# print('hello')
# yield 1
# print('world')
# yield 2
#
# g = func()
# a = g.__next__()
# print(a)
# b = g.__next__()
# print(b)
# yield關鍵字的特點: 可以記錄當前函式中執行的位置,下一次繼續執行
# next和yield是一對搭檔 : next開始函式的執行 yield停止函式的執行

生成器函式
 int 整數
# float 浮點數
# 1.2
# 2.3333344
# 256.789 = 2.56789*10**2
# 為什麼要叫浮點數 : 因為小數點是浮動的
# 浮點數能表示的數學上的數字 : 有理數(有限小數 無限迴圈小數)
# 浮點數的小數點是不準確的 : 小數的小數位是轉換成二進位制儲存
# a = 1.7265923649689710283508127969
# a = 1.111111111188818181818111624
# print(a)
#
# 轉換成字串儲存
# '1.71264864975975073507505'

# 如果你建立的變數本身帶小數點,那麼這個變數的資料型別直接就是浮點數
# 所有的除法(除了//)得到的都是小數
#
# 除法
# python2.x 整數除以整數就會取整(向下取整),有一個數浮點數,就按照浮點數計算
# python3.x 所有的除(除了//)的結果都是小數


# 生成器函式中
# send/__next__ 生成器函式之外用的
# yield/yield from 生成器函式之內用的
#
# next+send == yield
# 如果函式中的yield要接收引數,那麼應該使用send傳值
# 如果函式中的yield不需要接收引數,那麼應該使用next即可
#
# 生成器和迭代器是一樣的,內部的值都只能取一次
# 從生成器中取值的方式也和迭代器是一樣的:
# for
# next/send
# 資料型別的強制轉換(list)
# def gener():
# print('草莓味')
# yield 1
# print('香蕉味')
# yield 2
# print('榴蓮味')
# yield 3
#
# g = gener()
# num = g.__next__()
# num = g.__next__()
# num = g.__next__()
# print(num)
# for num in g:
# print('*'* num)

# def gener():
# print('草莓味')
# yield 1
# # smell = yield 1
# # print(smell)
# print('可樂味')
# smell2 = yield 2
# print(smell2)
# yield 3
#
# g = gener()
# print(g.__next__())
# ret = g.send('香蕉味') # g.__next__只不過傳了一個值進去
# print(ret)
# ret2 = g.send('榴蓮味')
# print(ret2)

列表推導式
# 和迴圈/列表相關的知識點
# l = [1,2,3,4,5,6]
# # [1,4,9,16,25,36]
# new_l = []
# for i in l:
# new_l.append(i*i)
# print(new_l)
#
# new_l2 = [i*i for i in l]
# print(new_l2)

# l = [1,2,3,4,5,6]
# print([i*i for i in l]) # 列表推導式
# 當已經有了一個列表,從這個列表中的每一個元素都需要做某個操作
# 並且需要將操作的結果放在一個新的列表中
# 適合使用列表推導式
# 新的列表 = [每一個元素要做的操作 for 列表中的每一個元素 in 列表]
# range(2,20) # 把每一個元素整除3的結果放到一個新的列表中
# new_lst = []
# for num in range(2,20):
# new_lst.append(num//3)

# lst = [num//3 for num in range(2,20)]
# print(lst)

# 請計算0-100內能被3整除的所有數字
# new_lst = []
# for i in range(0,101):
# if i%3 == 0:
# new_lst.append(i)
#
#
# new_lst2 = [i for i in range(0,101) if i%3 == 0]
# print(new_lst2)

生成器表示式
# 生成器表示式
# 1.想要一個生成器/迭代器 , 簡單的邏輯可以不寫函式而是直接用表示式實現
# 2.生成器表示式本身就是一個生成器/迭代器
# 3.惰性運算(列表推導式在執行完的那一刻,已經存在一個列表了) 只能取一次
# 生成器 只有 for next list才開始從生成器中取值 列表推導式
# 4.更加簡潔
# 生成器
# def func():
# for i in range(1000001):
# if i%3 == 0:
# yield i
#
# g1 = func()
# g1.__next__()

# g = (i for i in range(0,101) if i%3 == 0)
# print(g.__next__())
# print(g.__next__())