1. 程式人生 > >day011 函式名的運用,閉包,迭代器

day011 函式名的運用,閉包,迭代器

主要內容:
1.函式名的使用以及第一類物件
2.閉包
3.迭代器
一、函式名的運用
函式名就是變數名,命名規則與變數名一樣。
函式名儲存的是函式的記憶體地址。

1、檢視函式名的記憶體地址

"""python
def inf():
print("疏影")
print(inf)
# 結果
# <function inf at 0x0000019442C0A510>
"""

2、函式名可以賦值給其他變數

'''python
def inf():
print("疏影")
a = inf # 把函式當成一個變數賦值給另外一個變數
a() # 函式呼叫 inf()

'''

3、函式名可以當做容器類的元素


'''python
def inf():
print("疏影")
def inf1():
print("疏影")
lst = [inf, inf1] # 函式名作為列表的一個元素
for i in lst:
i() # 迴圈執行函式()

'''

4、把函式名當成變數來使用
代理模式
裝飾器的雛形

'''python
def inf():
print("疏影")
def inf2(fn):
print("一片")
fn() # 執行輸入的 fn
print("一片")
inf2(inf) # 把函式inf 作為引數傳遞給 inf2 的引數 fn

'''

5、函式名可以作為函式的返回值


'''python
def inf_1():
print("函式1")
def inf_2():
print("函式2")
print("函式1")
return inf_2

fn = inf_1() # 執行函式1,返回的是函式2,這時fn 指向函式2
fn() # 執行上面返回的函式2

'''

二、閉包
> * 閉包就是內層函式,對外層函式(非全域性)的變數的引用。
作用:
1.保護一個變數不受侵害
2.可以讓一變數常駐記憶體
1、可以使用 __closure__ 來檢測函式是否閉包, 返回 cell 就是閉包, None 就不是
fe:
'''python
def inf():
name = "疏影"
def inf2():
print(name) # 這個就是閉包
inf2()
print(inf2.__closure__) # (<cell at 0x00000234D6279648: str object at 0x00000234D6275978>,)
inf()
# 輸出結果: 疏影
'''
** 爬蟲 (low版本) 讓變數常駐記憶體的示例
'''
from urllib.request import urlopen # 開啟一個連線用的模組
# 外層函式
def but():
# 開啟連線. 讀取原始碼
content = urlopen("http://www.cctv.com/").read() # 永久駐留在記憶體
# 內層函式
def get_content():
# 返回content
return content
return get_content # 內層函式

fn = but() # 這裡會很慢. 需要網路請求
print(fn()) # 不會再進行網路請求了
print(fn()))

'''
三、迭代器

> * 常用命令
1.dir() 檢視變數能夠執行的方法(函式)
列印結果,如果有 __iter__() ,那麼這個類的物件就是可迭代物件
2.Iterator: 迭代器(本身就是一個可迭代物件), 內部包含 __iter__(), __next__()

3.Iterable: 可迭代的, 內部包含 __iter__()

> * 三大特徵
1. 省記憶體
2. 惰性機制
3. 只能往前. 不能後退

> * 從迭代器獲取資料的唯一方法: __next__()

1、for迴圈的流程(內部程式碼)

'''python
it = lst.__iter__() # lst為一個列表,即可迭代物件
while 1:
try: # 如果這個命令不成立,執行exectp
el = it.__next__() # for 迴圈的迴圈體
exectp StopItertationo:
break
''

2、如何判斷一個數據是否是可迭代物件
1.野路子,使用dir()
dir() -> __iter__ 可迭代的
dir() -> __next__ 迭代器
例:
'''python
lst = ["秦始皇", "漢武帝", "孝文帝", "隋煬帝", "李世民"]
print("__iter__" in dir(lst)) # True 可迭代的
print("__next__" in dir(lst)) # False 不是迭代器

print("__iter__" in dir(int)) # False 不迭代
print("__next__" in dir(int)) # False 不是迭代器

it = lst.__iter__() # 迭代器
print("__iter__" in dir(it)) # True 迭代器本身就是可迭代的
print("__next__" in dir(it)) # True
'''

2.官方的方法
collections 關於集合類的相關操作
Iterable : 可迭代的
Iterator : 迭代器
例:
'''python
lst = ["秦始皇", "漢武帝", "孝文帝", "隋煬帝", "李世民"]
from collections import Iterable, Iterator
print(isinstance(lst, Iterable)) # True
print(isinstance(lst, Iterator)) # False

print(isinstance({1,2,3}, Iterable)) # True, 可以使用for迴圈
'''