等會再寫吧,剛剛寫完一篇博客,我先寫信息安全讀書的筆記吧!python
寫完了,開始寫day11的總結吧c++
總結一波:今天學習了迭代對象、迭代器、函數名的用法、以及默認參數的坑、全局變量的修改和定義
迭代對象和迭代器,兩個很容易搞混,我以前一直覺得兩個是同樣的。直到昨天聽老師講了一遍,彷彿打開了一扇門😂,瞬間明白了。git
Python 中的迭代對象內部都有一個 __iter__
方法,這是一個重要的標誌。python 中一切皆對象,可認爲迭代對象是一個可迭代重複輸出的對象。常見的有:str、list、tuple、dict、set、range面試
這裏咱們使用 dir 打印對象的全部方法,看 __iter__
是否在裏面,api
>>> name = "python" >>> dir(name) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] >>> "__iter__" in dir(name) True
能夠看出字符串中是有 __iter__
方法的,同理能夠測試列表、元組、字典等。數組
迭代對象優勢:能夠直觀顯示內部數據,有不少方法,訪問速度快。迭代對象缺點:佔用存儲空間大,不能夠直接使用 for 循環,屬於典型的用空間複雜度換時間複雜度。安全
可是你可能會說爲啥字符串、列表、元組等都是能夠使用 for 循環的,這是由於當你使用 for 進行循環迭代對象的時候,Python 內部會默認將其轉成迭代器進行迭代循環。不懂迭代器嗎,那麼請看下面:bash
從字面上理解就是可迭代的工具,其最大的優勢在於節省內存空間,每次僅迭代讀取其中一部份內容,可是相對費時間,典型的用時間複雜度換空間複雜度。而且只能一步一步向下迭代,不可逆向迭代。app
怎麼判斷是否是迭代器呢?答:看是否包含有 __iter__
和 __next__
方法。目前已知的迭代器是讀取文件時的句柄f,能夠看下面的例子。ssh
>>> with open('test.txt', mode='r', encoding='utf8') as f: ... print(dir(f)) ... print('__iter__' in dir(f) and '__next__' in dir(f)) ... ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines'] True
經過使用 iter()
將迭代對象轉成迭代器
name = "python" item = iter(name) # 將迭代對象 str 類型的字符串轉成一個迭代器 # 二、打印迭代器的內容 使用 next 向後讀取 print(item.__next__()) # 或者是 等價 next(item) print(next(item)) # p # y
操做全局變量可用 global
:
可在局部中建立全局變量
# 一、局部中建立全局變量 name = "python" def test(): global age age = 17 print(age, name) # 17 python test() print(age) # 17
也可在局部中修改全局變量
# 二、局部中修改全局變量 name = "python" def test(): global name name = "I love python" print(name) # I love python test()
這裏須要注意的是,若是不在局部中聲明 name 是全局變量,那麼就沒法修改全局變量,而就變成定義一個叫 name 的局部變量。
操做局部變量可用 nonlocal
,做用:1.不能修改全局變量,2.用於內層函數對外層函數的數據修改。
例子:
# nonlocal 的用法 def test(): name = "I" def love(): nonlocal name # 若是此處不聲明 nonlocal 的話會報錯,找不到 name 變量 name += " love Python" print(name) # I love Python love() test()
這個做爲函數的一點補充,函數的名稱能夠做爲:
總的來講,函數名僅僅是一個函數的入口地址,運行時並不作實例化,只有調用時在進行解釋並實例化。
def test1(): """直接調用型""" print("func test1") def test2(func): """ :params func: 函數名 """ print("func test2") func() def test3(): """ :return: 函數名 """ print("func test3") return test1 func_list = [test1, test2, test3] print(func_list) # [<function test1 at 0x7fd89ecd4ee0>, <function test2 at 0x7fd89ecd4dc0>, <function test2 at 0x7fd89ecd4dc0>] # 一、函數名存在容器中 調用 func_list[0]() # func test1 # 二、函數名做爲函數的參數 func_list[1](test1) """ func test2 func test1 """ # 三、函數名做爲返回值 調用 func_list[2]()() """ func test3 func test1 """
注意面試的時候可不會讓你拿電腦跑代碼的,因此要用心思考。
(1)定義和引用順序問題:
# 一、默認參數的坑 def func(): print(count) count = 3 func() """你的結果是? 此處報錯:UnboundLocalError: local variable 'count' referenced before assignment 緣由:你在定義變量的前面引用變量了。 """
(2)默認參數的坑的題:
# 默認參數的坑 案例2.1def func(name, lis=[]): lis.append(name) print(lis)func('I')func('love')func('python')"""你的結果是?['I']['I', 'love']['I', 'love', 'python']"""
結果沒想到吧,這是由於函數默認的參數 lis
定義了一個空列表,有存儲地址。當你連續調用函數 func
時,傳入的參數都添加到 lis 中了,因此就是上面打印的數據了。
弄懂了嗎?來來試試第二個題
# 默認參數的坑 案例2.2def func(name, lis=[]): lis.append(name) print(lis)func('I')func('love', ['c++'])func('python')"""你的結果是?['I']['c++', 'love']['I', 'python']"""
你會發現和第一題的答案差別仍是很大的,爲啥呢?首先第二個調用 func ,傳入了一個列表設爲 lis2 ,這個 lis2 會替換掉函數參數中的 lis 的值。注意是替換而不是覆蓋,自己 lis 對應的存儲地址仍是有的,因此當第三個調用是 func 時,將 "python" 追加到了 lis 中,就變成了 ['I', 'python']。
寫總結真的很腦子,鍛鍊本身的總結能力。