2020_10_14_裝飾器、生成器和模組
有參裝飾器
1.有參裝飾器的功能
在給函式新增功能的時候可以通過引數控制具體的操作(操作不固定)
2.怎麼寫有參裝飾器
def 函式名0(裝飾器的引數列表)
def 函式名1(func):
def 函式名2(*args, **kwargs):
result = func(*arges, **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(‘after’)
def func1(x, y):
print(x+y)
func1(10, 20)
練習:寫一個裝飾器,在原函式返回值的基礎上減去指定的值
@sub(10) @sub(30)
def sub(num):
def test(func):
def new_func(*args, **kwargs):
result = func(*args, **kwargs)
if type(result) in (int, float, complex):
return result - num
return result
return new_func
return test
迭代器(iter)
1.迭代器是容器型資料型別(序列)
特點:a.不能同時檢視所有元素(列印看不到裡面的元素)
b.不能統計個數
c.獲取元素的時候只能一個一個的取(每次取最上層的那個),每次獲取元素該元素就會從迭代器中消失(取一個就少一個)
2.建立迭代器
迭代器的建立有兩種方式
1)通過iter將其他序列轉換成迭代器
2)建立生成器
iter1 = iter([10, 20, 30, 40])
print(iter1)
print(len(iter1)) # 報錯!
iter2 = iter(‘hello’)
print(iter2)
3.獲取元素
不管通過什麼樣的方式獲取到了迭代器中的元素,對應的元素都會從迭代器中消失
1)取單個元素
next(迭代器) - 獲取迭代器最上層的一個資料(如果迭代器為空,就會報StopIteration錯誤)
2)遍歷
for 變數 in 迭代器:
pass
print(next(iter1)) # 10
print(next(iter1)) # 20
next(iter1)
print(next(iter1)) # 40
print(next(iter1)) # 報錯! StopIteration
for x in iter2:
print(x)
print(next(iter2)) # 報錯! StopIteration
iter3 = iter(‘python!’)
list1 = list(iter3)
print(list1)
print(next(iter3)) # 報錯! StopIteration
iter4 = iter(‘python123’)
next(iter4)
for x in iter4:
print(‘x:’, x)
生成器(generator)
1.生成器的本質就是迭代器(迭代器的特點和獲取元素的方式生成器都適用)
2.怎麼建立生成器
呼叫一個帶有yield關鍵字的函式就可以建立一個生成器物件
(如果被呼叫的函式裡面有yield,不會執行函式體,也不會獲取函式返回值)
def func1():
print(’======’)
print(’++++++’)
yield
return 100
re = func1()
print(re) # <generator object func1 at 0x10d9380d0>
3.怎麼確定生成器中產生的資料
“”"
產生資料的個數: 看執行完生成器對應的函式的函式體會遇到幾次yield()
產生的資料的值: 看每次遇到的yield後面的資料是什麼,沒有資料就是None
def func2():
yield 100
yield ‘abc’
for x in range(3):
yield x
gen1 = func2()
print(gen1)
print(list(gen1)) # [100, ‘abc’, 0, 1, 2]
def func3(x):
yield 10
if x & 1:
yield 20
return 30
yield 30
gen2 = func3(5)
print(list(gen2)) # [10, 20]
gen3 = func3(4)
print(list(gen3)) # [10]
4.生成器產生資料的原理
呼叫函式建立生成器物件的時候不會執行函式體,獲取生成器中的元素的時候才會執行。
第一次獲取元素會從函式體開始的位置開始執行,執行到第一次yield就停下來,並且將yield後面的資料作為這次獲取到的元素。後面每次獲取元素的時候都是從上次結束的位置接著往後執行,執行到下一次yield又會停下來。如果從當前位置開始執行到函式結束沒有遇到yield,如果是next就會報StopIteration錯誤。
def func4():
print(‘1’)
yield 100
print(‘2’)
yield 200
print(‘3’)
yield 300
gen4 = func4()
print(next(gen4))
for _ in range(5):
print(’~~~~~~~~~~’)
print(next(gen4))
print(next(gen4))
print(next(gen4)) # 報錯! StopIteration
gen5 = func4()
gen6 = func4()
print(next(gen5)) # 100
print(next(gen5)) # 200
print(next(gen6)) # 100
def func5():
for x in range(5):
yield x*2
print(next(func5())) # 0
print(next(func5())) # 0
練習:寫一個產生學號的生成器,能夠產生指定學科001~999的學生學號
python學生: python001 ~ python999
java學生:java001 ~ java999
def create_num(subject: str):
for x in range(1, 1000):
yield f’{subject}{x:0>3}’
# yield subject+str(x).zfill(3)
python_nums = create_num(‘python’)
print(next(python_nums))
print(next(python_nums))
java_num = create_num(‘java’)
print(next(java_num))
練習: 寫一個偶數生成器,能夠產生所有的正的偶數
def even_numbers():
num = 2
while True:
yield num
num += 2
even_gen = even_numbers()
for _ in range(100):
print(next(even_gen))
print(’=============’)
for _ in range(50):
print(next(even_gen))
4.生成式 - 生成器的推導式
將列表推導式的[]變成()就是生成器的推導式即生成式
result = (x**2 for x in range(10))
print(result) # <generator object at 0x1018bd5d0>
print(next(result))
print(next(result))
print(next(result))
for item in result:
print(f’item:{item}’)
模組
1.python中一個py檔案就是一個模組。
可以在一個模組中去使用另外一個模組中的內容(全域性變數),但是需要提前匯入模組
2.匯入模組
1)import 模組名
a.匯入能夠使用指定模組中所有的全域性變數;
b.以 ‘模組名.變數’ 形式去使用變數
2)from 模組名 import 變數名1,變數名2,…
a.匯入模組,能使用模組中指定的全域性變數;
b.直接使用對應的變數,不需要在前面加 ‘模組名.’
3)import 模組名 as 新模組名
匯入模組的時候對模組進行重新命名,重新命名後需要通過新模組名來使用被匯入的模組
- from 模組名 import 變數 as 新變數名, …
匯入模組的時候對指定變數進行重新命名
5)(瞭解)from 模組名 import *
匯入模組中所有的全域性變數
匯入方式一: import 模組名
import test1
print(test1.A)
test1.func1()
print(test1.X)
匯入方式二:from 模組名 import 變數
from test1 import A, func1
print(A)
func1()
匯入方式三:模組重新命名
import test1 as ts1
test1 = 10
test2 = 200
for x in range(test1):
print(x)
呼叫func1
ts1.func1()
print(ts1.A)
print(ts1.X)
匯入方式四:對變數重新命名
from test1 import func1 as ts_func1, A, X as ts_X
def func1():
print(‘本模組中的func1’)
func1()
ts_func1()
print(A, ts_X)
3.匯入模組的原理
不管是通過import還是from-import,在匯入模組的時候,系統會自動將被匯入的模組
中所有的程式碼都執行一遍
注意:import匯入模組的時候,自帶查重功能(如果被匯入的模組已經被匯入過,不會重複匯入)
from test1 import A
print(‘A:’, A)
4.阻止匯入
定義模組的時候,可以通過 ‘if name == “main”’ 這個if語句來阻止模組中的指定程式碼被其他模組在匯入的執行。(在這個if語句中的程式碼不會被其他模組執行,不在這個if語句中的程式碼就會被其他模組執行)
原理:
每個py檔案中預設都有一個變數 name 用來儲存當前模組的模組名,
當直接執行某個py檔案的時候這個檔案中的__name__會自動變成 “main”
import test2
print(‘06:’, name)
相關文章
- Python之裝飾器、迭代器和生成器Python
- Python迭代器&生成器&裝飾器Python
- python_裝飾器——迭代器——生成器Python
- 詳解python三大器——迭代器、生成器、裝飾器Python
- Django CBV裝飾器 中介軟體 auth模組 CSRF跨站請求Django
- flask_login模組中user_loader裝飾器引發的思考Flask
- python裝飾器2:類裝飾器Python
- Python學習之三大名器-裝飾器、迭代器、生成器Python
- Python_閉包和裝飾器Python
- python的裝飾器和閉包Python
- 插片式遠端IO模組:單通道PNP和NPN編碼器模組功能和安裝方法
- Python 裝飾器Python
- Python裝飾器Python
- 類裝飾器
- JS裝飾器JS
- OpenHarmony裝飾指定自定義元件:@BuilderParam裝飾器元件UI
- 使用 TypeScript 裝飾器裝飾你的程式碼TypeScript
- 裝飾器與後設資料反射(1)方法裝飾器反射
- Python提高:關於閉包和裝飾器Python
- Python進階之閉包和裝飾器Python
- 模組的釋出和安裝
- decorator-裝飾器
- 裝飾器函式函式
- Python 裝飾器原理Python
- 裝飾器模式(Decorator)模式
- Python裝飾器模式Python模式
- 裝飾器&遞迴遞迴
- Javascrip—裝飾器(7)Java
- 1.5.3 Python裝飾器Python
- wrap裝飾器包
- Python 裝飾器(一)Python
- python的裝飾器Python
- react 理解裝飾器React
- 裝飾器的使用
- JS 裝飾器解析JS
- 裝飾器與後設資料反射(3)引數裝飾器反射
- python極簡教程06:生成式和裝飾器Python
- Python中裝飾器的基本概念和用法Python