有參裝飾器的功能 - 在給函數新增功能的時候可以通過引數控制具體的操作(操作不固定)
2.怎麼寫有參裝飾器
"""
def 函數名0(裝飾器的參數列):
def 函數名1(func):
def 函數名2(*args, **kwargs):
result = func(*args, **kwargs)
新功能
return result
return 函數名2
return 函數名1
def 函數名(裝飾器的參數列):
無參裝飾器
return 無參裝飾器的函數名
有參裝飾器的用法:
@函數名0(裝飾器實參列表)
"""
# 寫一個裝飾器可以在函數結束後列印指定的任意提示資訊
def add_message(msg):
def test1(func):
def new_func(*args, **kwargs):
result = func(*args, **kwargs)
print(msg)
return result
return new_func
return test1
@add_message('結束')
def func1(x, y):
print(x+y)
func1(10, 20)
# 練習:寫一個裝飾器,在原函數返回值的基礎上減去指定的值
# @sub(10) @sub(30)
def sub(num):
def test2(func):
def new_func(*args, **kwargs):
result = func(*args, **kwargs)
if type(result) in (int, float, bool, complex):
return result-num
return result
return new_func
return test2
@sub(20)
def func2(x, y):
return x*y
print(func2(10, 20))
1.什麼是迭代器(iter)
"""
迭代器是容器型資料型別(序列),
特點:a.不能同時檢視所有元素(列印看不到裡面的元素)
b.不能統計個數
c.獲取元素的時候只能一個一個的取(每次取最上層的那個),每次獲取元素該元素就會從迭代器中消失(取一個就少一個)
"""
2.建立迭代器物件
"""
迭代器建立有兩種方式
1)通過iter將其他序列轉換成迭代器
2)建立生成器
"""
iter1 = iter([10, 20, 30, 40])
print(iter1) # <list_iterator object at 0x000001BC01F4B198>
# print(len(iter1)) # TypeError: object of type 'list_iterator' has no len()
3.獲取元素
不管通過什麼樣的方式獲取到了迭代器中的元素,對應的元素都會從迭代器中消失
"""
1)取單個元素
next(迭代器) - 獲取迭代器最上面的一個資料(如果迭代器為空,就會報StopIteration錯誤)
2)遍歷
for 遍歷 in 迭代器:
pass
"""
print(next(iter1)) # 10
print(next(iter1)) # 20
next(iter1) # 30
print(next(iter1)) # 40
# print(next(iter1)) # StopIteration
iter2 = iter('hello')
for i in iter2:
print(i)
iter3 = iter('python!')
list1 = list(iter3)
print(next(iter3)) # StopIteration
iter4 = iter('python123')
next(iter4)
for i in iter4:
print('i', i)
1.什麼是生成器(generator)
"""
生成器的本質就是迭代器(迭代器的特點和獲取元素的方式生成器都適用)
"""
2.怎麼建立生成器
"""
呼叫一個帶有yield關鍵字的函數就可以建立一個生成器物件
(如果被呼叫的函數裡面有yield,不會執行函數體也不會獲取函數返回值)
"""
def func1():
print('=====')
print('+++++')
yield
return 100
re = func1()
print(re) # <generator object func1 at 0x0000020B004BBBF8>
3.怎麼確定生成器中產生的資料
"""
產生資料的個數:看執行完生成器對應的函數的函數體會遇到幾次yield
產生的資料的值:看每次遇到的yield後面的資料是什麼,沒有資料就是None
"""
def func2():
yield 100
yield 'abc'
for i in range(3):
yield i
gen1 = func2()
# print(gen1)
# print(len(gen1)) # TypeError: object of type 'generator' has no len()
# print(len(list(gen1))) # 5
print(list(gen1)) # [100, 'abc', 0, 1, 2]
4.生成器產生資料的原理
"""
呼叫函數建立生成器物件的時候不會執行函數體,獲取生成器中的元素的時候才會執行。
第一次獲取元素會從函數體開始的位置開始執行,執行到第一次yield就停下來,並且將yield後面的資料作為這次獲取到的元素。
後面每次獲取元素的時候都是從上次結束的位置接著往後執行,執行到下一次yield又會停下來。如果從當前位置開始執行到函數結束沒有遇到yield,如果是next就會報StopIteration錯誤
"""
def func4():
print('======1======')
yield 100
print('======2======')
yield 200
print('======3======')
yield 300
gen2 = func4()
print(next(gen2))
for i in range(3):
print('````````')
print(next(gen2))
print(next(gen2))
# print(next(gen2)) # StopIteration
gen3 = func4()
gen4 = func4()
print(next(gen3)) # 100
print(next(gen3)) # 200
print(next(gen4)) # 100
def func5():
for i in range(5):
yield i*2
# 重新呼叫函數則會重新開始
print(next(func5())) # 0
print(next(func5())) # 0
# 練習:寫一個產生學號的生成器,能夠產生指定學科001~999的學生學號
# python學生:python001~python999
# java學生:java001~java999
def student_id(str:str):
for i in range(1, 1000):
yield f'{str}{i:0>3}'
# yield str+str(i).zfill(3)
py = student_id('python')
for i in range(1, 1000):
print(next(py))
ja = student_id('java')
for i in range(1, 1000):
print(next(ja))
# 練習:寫一偶數個生成器,能夠產生所有的正的偶數
def even():
num = 2
while True:
yield num
num += 2
even1 = even()
print(next(even1))
print(next(even1))
4.生成式 - 生成器的推導式
"""
將列表推導式[]變成(),建立的就是生成器的推導式即生成式
"""
test模組
print('==========test開始==========')
A = 100
def func1():
print('test1中的函數')
for X in range(10):
pass
print('==========test結束==========')
test1模組
def sum1():
print(sum(range(100)))
def main():
sum1()
if __name__ == '__main__':
main()
1.什麼是模組
"""
python中一個py檔案就是一個模組。
可以在一個模組中去使用另外一個模組的內容(全域性變數),但需要提前匯入模組
"""
2.匯入模組
"""
1)import 模組名 - 匯入能夠使用指定模組中所有的全域性變數;
以'模組名.變數'形式去使用
2)from 模組名 import 變數名1,變數名2,...
a.匯入模組,能使用模組中指定的全域性變數;
b.直接使用對應的變數,不需要在前面加'模組名.'
3)import 模組名 as 新模組名
匯入模組的時候對模組進行重新命名,重新命名後需要通過新模組名來使用被匯入的模組
4)from 模組名 import 變數 as 新變數名,...
匯入模組的時候對指定變數進行重新命名
5)from 模組名 import *
匯入模組中所有的全域性變數
"""
# 匯入方式一:import 模組名
import test
print(test.A)
test.func1()
print(test.X)
# 匯入方式二:from 模組名 import 變數
from test import A, func1
print(A)
func1()
# 匯入方式三:模組重新命名
import test as ts
ts.func1()
print(ts.A)
print(ts.X)
# 本模組中的變數名與匯入模組的變數名都可以使用
# 匯入方式四:對變數重新命名
from test import func1 as ts_func1
def func1():
print('本模組中的func1')
func1() # 本模組中的func1
ts_func1() # test1中的函數
3.匯入模組的原理
"""
不管是通過import還是from-import,在匯入模組的時候,系統會自動將被匯入的模組中所有的程式碼都執行一遍
注意:import匯入模組的時候,自帶查重功能(如果被匯入的模組已經被匯入過,不會重複匯入)
"""
import test
import test
# *import 自帶檢測重複匯入的功能*
4.阻止匯入
"""
定義模組的時候,可以通過if __name__ == '__main__' 這個if語句來阻止模組
中的指定程式碼被其他模組在匯入的執行。(在這個if語句中的程式碼不會被其他模組執行,
不在這個if語句中的程式碼就會被其他模組執行)
原理:
每個py檔案中預設都有一個變數 __name__ 用來儲存當前模組的模組名,
當直接執行某個py檔案的時候這個檔案中的__name__會自動變成"__main__"
"""