迭代器

主要內容: python

  • 1. 函數名的使用以及第⼀類對象
  • 2. 閉包
  • 3. 迭代器

1. 函數名的使用以及第⼀類對象設計模式

  函數名是一個變量, 但它是一個特殊的變量, 與括號配合能夠執行函數的變量。閉包

(1) 函數名的內存地址函數

def func():
    print("呵呵")
print(func)            #<function func at 0x000001EBCE5D6048>

(2)函數名能夠賦值給其餘變量spa

def func():
    print("呵呵")
print(func)
a = func      # 把函數當成⼀個變量賦值給另⼀個變量
a()           # 函數調⽤用 func()       #呵呵

(3)函數名能夠當作容器類的元素設計

def func1():
    print("呵呵")
def func2():
    print("呵呵")
def func3():
    print("呵呵")
def func4():
    print("呵呵")
lst = [func1, func2, func3]
for i in lst:
    i()

(4)函數名能夠當作函數的參數代理

def func():
    print("吃了了麼")
def func2(fn):
    print("我是func2")
    fn()    # 執行傳遞過來的fn
    print("我是func2")
func2(func)     # 把函數func當成參數傳遞給func2的參數fn.

(5)函數名能夠做爲函數的返回值code

def func_1():
    print("這里是函數1")
    def func_2():
            print("這里是函數2")
    print("這里是函數1")
    return func_2
fn = func_1()   # 執⾏函數1.  函數1返回的是函數2, 這時fn指向的就是上面函數2
fn()    # 執⾏上面返回的函數

(6) 一個設計模式對象

def panpan():
    print("我是潘潘. 我喜歡毒丈夫 ")
def xiaoping():
    print("我是小萍萍. 我喜歡毒丈夫 ")
def daguanren():
    print("大官人喜歡xxxx")
def wangpo(nv, nan): # 核心業務邏輯
    nv()
    nan()
wangpo(xiaohua, daguanren)             # 王婆代理了大官人和潘潘

(7)函數名既然是變量,變量名是任意的,在屢次的賦值和調用過程當中後續可能不知道初始的變量名,能夠經過.__name__ 來獲得初始的變量名blog

def chi():
    print("我是吃")
a = chi
haha = a
hehe = haha
bilibili= hehe
bilibili()
print(bilibili.__name__) # 函數名

(8)函數的註釋

def play(wanjv1, wanjv2, wanjv3):
    '''
        這是一個關於玩兒的函數
        :param wanjv1: 玩具1
        :param wanjv2: 玩具2
        :param wanjv3: 玩具3
        :return: 開心
    '''
    print("我要玩兒盪鞦韆")
    return "開心"
# play("獨木橋", "獨輪車", "獨眼龍")
print(play.__doc__) #  document   以文檔的形式查看註釋
print(str.join.__doc__)   #查看join裏面是什麼東西
#結果:
# 這是一個關於玩兒的函數
# :param
# wanjv1: 玩具1
# :param
# wanjv2: 玩具2
# :param
# wanjv3: 玩具3
# :return: 開心
# 
# S.join(iterable) -> str

# Return a  string which is the  concatenation of the strings in the iterable.The separator between elements is S.

2. 閉包

  閉包就是內層函數, 對外層函數(非全局)的變量的引用. 叫閉包

def func1():
    name = "alex"
    def func2():
        print(name)     # 閉包
    func2()
func1()       # alex

咱們可使用__closure__來檢測函數是不是閉包. 使用函數名.__closure__返回cell就是閉包,返回None就不是閉包

def func1():
    name = "alex"
    def func2():
        print(name)     # 閉包
    func2()
    print(func2.__closure__)     #(<cell at 0x000001AF73627588: str object at 0x000001AF736B7378>,)
func1()       # alex

在函數外邊調用內部函數

def outer():
    name = "alex"
    # 內部函數
    def inner():
        print(name)
    return inner
fn = outer()         # 訪問外部函數, 獲取到內部函數的函數地址
fn()                 # 訪問內部函數

若是多層嵌套,只須要一層一層的往外層返回

def func1():
    def func2():
        def func3():
            print("嘿嘿")
        return func3
    return func2
func1()()()

閉包的好處: 

  • 當在外界訪問內部函數時, 那這個時候內部函數訪問的時間和時機就不⼀定了,由於在外部, 能夠選擇在任意的時間去訪問內部函數.
  • 若是⼀個函數執行完畢, 則這個函數中的變量以及局部命名空間中的內容都將會被銷燬. 在閉包中若是變量被銷燬了, 那內部函數將不能正常執行.
  • python規定:若是你在內部函數中訪問了外層函數中的變量,那麼這個變量將不會消亡. 將會常駐在內存中,這樣閉包能夠保證外層函數中的變量在內存中常駐.

3. 迭代器

 str, list, tuple, dict, set. 那爲什麼咱們能夠稱他們爲可迭代對象呢, 由於他們都遵循了可迭代協議.

# 對的
s = "abc"
for c in s:
    print(c)
    
#  錯的
for i in 123:
 print(i)
結果:

Traceback (most recent call last):
 File "E:/Python_workspace/day 011/011整理.py", line 111, in <module>
  for i in 123:
TypeError: 'int' object is not iterable

 'int' object is not iterable' 即若是整數類型對象是不可迭代的,iterable表示可迭代的,表示可迭代協議,咱們能夠經過dir函數來查看類中定義好的

    全部包含了__iter__的東西均可以使用for循環. 均可以進行迭代

s = "個人哈哈哈"
print(dir(s))       # 能夠打印對象中的⽅方法和函數
print(dir(str))     # 也能夠打印類中聲明的⽅方法和函數
s = "alex"
print(dir(s)) # 在字符串中發現了__iter__. 沒有__next__
a = 123
print(dir(a)) # 在int中沒有__iter__ 沒有__next__
lst = [1, 2, 3,]
print(dir(lst)) # 在list中也有__iter__

   (1)調用了__iter__(), 訪問__iter__()能夠獲得迭代器

lst = [1, 2, 3, 4, 5, 6]
it = lst.__iter__()  # iterator 迭代器
while 1:
    try:
        print(it.__next__())
    except StopIteration:
        print("結束了")
        break
for el in lst:
    print(el)
else:
    print("結束了")

(2) 迭代器給全部的數據類型提供了一種統一的遍歷的方式(可迭代協議), Iterable, __iter__()

 

lst = [1, 2, 3, 4, 5]
print("__iter__" in dir(lst))    #True
print("__next__" in dir(lst))    #False

 

 

lst = [1, 2, 3, 4, 5]
it = lst.__iter__()
print("__iter__" in dir(it)) #  迭代器裏面是有__iter__的.  迭代器必定是可迭代的     #True
print("__next__" in dir(it))                                                     #True
#
for el in it: # 迭代器可使用for循環
    print(el)

 

 Iterable: 可迭代對象. 內部包含__iter__()函數       

 Iterator: 迭代器. 內部包含__iter__() 同時包含__next__(). 

from collections import Iterable # 可迭代的
from collections import Iterator # 迭代器
#
lst = ["周潤發","麻花藤","劉偉"]
print(isinstance(lst, Iterable)) # instance  實例, 對象    #True
print(isinstance(lst, Iterator)) # instance  實例, 對象    #False
#
it = lst.__iter__()
print(isinstance(it, Iterable)) # instance  實例, 對象      #True
print(isinstance(it, Iterator)) # instance  實例, 對象       #True

 

 迭代器的特色:             

  • 1. 節省內存.           
  • 2. 惰性機制           
  • 3. 不能反覆, 只能向下執行
相關文章
相關標籤/搜索