python 高級(jí) 13閉包 裝飾器

閉包和裝飾器

1.8 閉包和裝飾器

學(xué)習(xí)目標(biāo)

? 1. 能夠說出閉包的定義形式

? 2. 能夠說出裝飾器的實(shí)現(xiàn)形式

? 3. 能夠說出裝飾器的作用

? 4. 能夠說出裝飾器的不同形式

? 5. 能夠說出萬(wàn)能裝飾器的實(shí)現(xiàn)形式

? 6. 能夠說出裝飾器的執(zhí)行過程

--------------------------------------------------------------------------------

1.8.1 閉包和裝飾器概述

? 什么是閉包:

? ? ? 閉包是指在一個(gè)函數(shù)中定義了一個(gè)另外一個(gè)函數(shù),內(nèi)函數(shù)里運(yùn)用了外函數(shù)的臨時(shí)變量(實(shí)際參數(shù)也是臨時(shí)變量),并且外函數(shù)的返回值是內(nèi)函數(shù)的引用(一切皆引用,所有的函數(shù)名字都只是函數(shù)體在內(nèi)存空間的一個(gè)引用。)

? 閉包的作用:

? ? ? 可以隱藏內(nèi)部函數(shù)的工作細(xì)節(jié),只給外部使用者提供一個(gè)可以執(zhí)行的內(nèi)部函數(shù)的引用。

? ? ? 避免了使用全局變量,保證了程序的封裝性

? ? ? 保證了內(nèi)函數(shù)的安全性,其他函數(shù)不能訪問

? 什么是裝飾器:

? ? ? 裝飾器就是用于拓展已有函數(shù)功能的一種函數(shù),這個(gè)函數(shù)的特殊之處在于它的返回值也是一個(gè)函數(shù),實(shí)際上就是利用閉包語(yǔ)法實(shí)現(xiàn)的。

? 裝飾器的作用

? ? ? 在不用更改原函數(shù)的代碼前提下給函數(shù)增加新的功能。

1.8.2 思考

有一種叫做五步棋的游戲,在一個(gè) 五行五列的網(wǎng)格上雙方各持一色棋子,在棋子移動(dòng)時(shí),只能以橫向或縱向的形式移動(dòng)。

如果實(shí)現(xiàn)游戲,如何能記錄當(dāng)前棋子移動(dòng)的位置(也就是坐標(biāo))呢?

1.8.3 技術(shù)點(diǎn)回顧

在使用函數(shù)時(shí),函數(shù)可以傳遞參數(shù),函數(shù)也可以返回?cái)?shù)據(jù)。

在傳遞和返回?cái)?shù)據(jù)時(shí),一般是傳遞返回的固定數(shù)據(jù)和代碼執(zhí)行的結(jié)果。

在Pyhton中,函數(shù)也是一個(gè)對(duì)象,在函數(shù)操作中,函數(shù)對(duì)象也可以當(dāng)成一個(gè)參數(shù)或一個(gè)返回值進(jìn)行返回。

當(dāng)程序內(nèi)或程序外拿到參數(shù)的引用后就可以直接使用這個(gè)函數(shù),(原理回想下深淺拷貝中的賦值)

def show():

? ? print('show run')

show()

func = show

func()

程序執(zhí)行結(jié)果:

show run

show run

1.8.4 閉包

? 閉包就是在一個(gè)外部函數(shù)中定義了一個(gè)內(nèi)部函數(shù),并且在內(nèi)部函數(shù)中使用了外部函數(shù)的變量,并返回了內(nèi)部函數(shù)的引用。

? nonlocal 的使用

? ? ? nonlocal 變量名 ——》聲明變量為非本地變量

? ? ? 如果在閉包的內(nèi)部函數(shù)中直接使用外部函數(shù)的變量時(shí),不需要任何操作,直接使用就可以了。

? ? ? 但是如果要修改外部變量的值,需要將變量聲明為 nonlocal,那么建議將 nonlocal 寫在內(nèi)部函數(shù)的第一行。

利用函數(shù)可以被傳遞和返回的特性,在開發(fā)過程中,可以隱藏更多的實(shí)現(xiàn)細(xì)節(jié)。

n = 1? # 全局變量

def show(): # 公有函數(shù)

? ? print('show: ',n)

def callFunc(func): #公有函數(shù)

? ? return func

s = callFunc(show)? # 函數(shù)執(zhí)行

s()

show()

在這段代碼中,在實(shí)際開發(fā)中并沒有實(shí)際意義,只是簡(jiǎn)單示意了函數(shù)可以被當(dāng)做參數(shù)和返回值使用。

但是這段代碼并不完美

第一,盡量不要使用全局變量,因?yàn)槿肿兞繒?huì)破壞程序的封裝性。

第二,如果 show 函數(shù)不想被 callFunc 以外的函數(shù)進(jìn)行訪問時(shí),是無法控制的。

所以可以改進(jìn)如下:

def callFunc():

? ? n = 1

? ? def show():

? ? ? ? print('show: ', n)

? ? return show

s = callFunc()

s()

# show() 因?yàn)?show 函數(shù)定義在 callFunc 內(nèi)部,所以外部不可見,不能使用

代碼改進(jìn)后,去掉了全局變量的使用。而且將 show 函數(shù)封裝在了 callFunc 函數(shù)內(nèi)部,使外部不可見,不能使用 show 函數(shù),隱藏了實(shí)現(xiàn)細(xì)節(jié)

程序在執(zhí)行時(shí),callFunc 函數(shù)返回了內(nèi)部定義的 show 函數(shù),并且 在 show 函數(shù)內(nèi)部使用了外部函數(shù)的變量。

在 show 函數(shù)返回時(shí),保存了當(dāng)前的執(zhí)行環(huán)境,也就是會(huì)在 show 函數(shù)中使用的外部變量 n 。

因?yàn)?n 是一個(gè) callFunc 函數(shù)中的局部變量,正常情況下 callFunc 函數(shù)執(zhí)行結(jié)束后,n 就會(huì)被釋放。

但是現(xiàn)在因?yàn)?callFunc 函數(shù)中返回了 show 函數(shù),show 函數(shù)在外部還會(huì)再執(zhí)行,所以程序會(huì)將 show 函數(shù)所需的執(zhí)行環(huán)境保存下來。

這種形式就是閉包。

? 利用閉包完成棋子的移動(dòng)

'''閉包實(shí)現(xiàn)棋子移動(dòng)'''

# 定義一個(gè)外部函數(shù)

def outer():

? ? # 在外部函數(shù)中定義一個(gè)保存坐標(biāo)的列表

? ? position = [0,0]

? ? # 定義一個(gè)內(nèi)部函數(shù),參數(shù)為移動(dòng)方式和步長(zhǎng)

? ? # 移動(dòng)方式為列表 [x,y] x,y分別只能取 -1,0,1三個(gè)值,表示反向,不動(dòng),正向

? ? def inner(direction,step):

? ? ? ? # 計(jì)算坐標(biāo)值

? ? ? ? position[0] = position[0] + direction[0] * step

? ? ? ? position[1] = position[1] + direction[1] * step

? ? ? ? # 返回移動(dòng)后的坐標(biāo)

? ? ? ? return position

? ? # 返回內(nèi)部函數(shù)

? ? return inner

# 獲取內(nèi)部函數(shù)

move = outer()

# 移動(dòng)

print(move([1, 0], 10))

print(move([0, 1], 10))

print(move([-1, 0], 10))

程序執(zhí)行結(jié)果:

[10, 0]

[10, 10]

[0, 10]

nonlocal 的使用 如果在閉包的內(nèi)部函數(shù)中直接使用外部函數(shù)的變量時(shí),不需要任何操作,直接使用就可以了。

但是如果要修改外部變量的值,需要將變量聲明為 nonlocal

def callFunc():

? ? m = 1

? ? n = 2

? ? def show():

? ? ? ? print('show - m: ', m)

? ? ? ? nonlocal n #如果不加會(huì)報(bào)錯(cuò)。

? ? ? ? n *= 10

? ? ? ? print('show - n: ', n)

? ? return show

s = callFunc()

s()

nonlocal 聲明變量為非本地變量,如果確定在程序要修改外部變量,那么建議將 nonlocal 寫在內(nèi)部函數(shù)的第一行。

小結(jié): 閉包就是在一個(gè)外部函數(shù)中定義了一個(gè)內(nèi)部函數(shù),并且在內(nèi)部函數(shù)中使用了外部函數(shù)的變量,并返回了內(nèi)部函數(shù)。

1.8.5 裝飾器

? 裝飾器的定義:

? ? ? 不改變?cè)泻瘮?shù)功能的基礎(chǔ)上,對(duì)函數(shù)進(jìn)行擴(kuò)展的形式,稱為裝飾器。

? 裝飾器的本質(zhì):

? ? ? 實(shí)際上就是一個(gè)以閉包的形式定義的函數(shù) 。

? 裝飾器的作用:

? ? ? 為現(xiàn)有存在的函數(shù),在不改變函數(shù)的基礎(chǔ)上去增加一些功能進(jìn)行裝飾。

? 裝飾器函數(shù)的使用:

? ? ? 在被裝飾的函數(shù)的前一行,使用 @xxx (@裝飾器(閉包)函數(shù)名) 形式來裝飾

? 裝飾器的好處:

? ? ? 定義好了裝飾器(閉包)函數(shù)后,只需要通過 @xxx (@裝飾器(閉包)函數(shù)名)形式的裝飾器語(yǔ)法,將 @xxx (@裝飾器(閉包)函數(shù)名) 加到要裝飾的函數(shù)前即可。

? 裝飾器的原理:

? ? ? 在執(zhí)行 @xxx 時(shí) ,實(shí)際就是將 原函數(shù)傳遞到閉包函數(shù)中,然后原函數(shù)的引用指向閉包返回的裝飾過的內(nèi)部函數(shù)的引用。

? ? ? @count_time? ? # 這實(shí)際就相當(dāng)于解決方法3中的 my_count = count_tiem(my_count)(把被裝飾的函數(shù)引用當(dāng)作參數(shù)傳入到裝飾器函數(shù),被裝飾的函數(shù)引用指向裝飾器函數(shù)返回的引用)

實(shí)例應(yīng)用

現(xiàn)在一個(gè)項(xiàng)目中,有很多函數(shù) ,由于項(xiàng)目越來越大,功能越來越多,導(dǎo)致程序越來越慢。

其中一個(gè)功能函數(shù)功能,實(shí)現(xiàn)一百萬(wàn)次的累加。

def my_count():

? ? s = 0

? ? for i in range(1000001):

? ? ? ? s += i

? ? print('sum : ', s)

現(xiàn)在想計(jì)算一下函數(shù)的運(yùn)行時(shí)間,如何解決?如何能應(yīng)用到所有函數(shù)上?

解決辦法 1

start = time.time()

my_count()

end = time.time()

print('共計(jì)執(zhí)行:%s 秒'%(end - start)) # 使用%d顯示,取整后是0秒,因?yàn)椴坏揭幻?/p>

這種辦法是最簡(jiǎn)單的實(shí)現(xiàn)方式,但是一個(gè)函數(shù)沒問題,但是要有1000個(gè)函數(shù),那么每個(gè)函數(shù)都要寫一遍,非常麻煩并且代碼量憑空多了三千行。

這明顯是不符合開發(fā)的原則的,代碼太冗余

解決辦法 2

def count_time(func):

? ? start = time.time()

? ? func()

? ? end = time.time()

? ? print('共計(jì)執(zhí)行:%s 秒'%(end - start)) # 使用%d顯示,取整后是0秒,因?yàn)椴坏揭幻?/p>

count_time(my_count)

經(jīng)過修改后,定了一個(gè)函數(shù)來實(shí)現(xiàn)計(jì)算時(shí)間的功能,通過傳參,將需要計(jì)算的函數(shù)傳遞進(jìn)去,進(jìn)行計(jì)算。

修改后的代碼,比之前好很多。

但是在使用時(shí),還是需要將函數(shù)傳入到時(shí)間計(jì)算函數(shù)中。

能不能實(shí)現(xiàn)在使用時(shí),不影響函數(shù)原來的使用方式,而又能實(shí)現(xiàn)計(jì)算功能呢?

解決辦法 3

def count_time(func):

? ? def wrapper():? ? ? #wrapper 裝飾

? ? ? ? start = time.time()

? ? ? ? func()

? ? ? ? end = time.time()

? ? ? ? print('共計(jì)執(zhí)行:%s 秒'%(end - start)) # 使用%d顯示,取整后是0秒,因?yàn)椴坏揭幻?/p>

? ? return wrapper

my_count = count_time(my_count)

my_count()

此次在解釋辦法2的基礎(chǔ)上,又將功能外添加了一層函數(shù)定義,實(shí)現(xiàn)了以閉包的形式來進(jìn)行定義

在使用時(shí),讓 my_count 函數(shù)重新指向了 count_time 函數(shù)返回后的函數(shù)引用。這樣在使用 my_count 函數(shù)時(shí),就和原來使用方式一樣了。

這種形式實(shí)際上就是塌裝飾器的實(shí)現(xiàn)原理。

之前我們用過裝飾器,如:@property 等

那么是否可以像系統(tǒng)裝飾器一樣改進(jìn)呢?

解決辦法 4

import time

def count_time(func):

? ? def wrapper():? ? ? #wrapper 裝飾

? ? ? ? start = time.time()

? ? ? ? func()

? ? ? ? end = time.time()

? ? ? ? print('共計(jì)執(zhí)行:%s 秒'%(end - start)) # 使用%d顯示,取整后是0秒,因?yàn)椴坏揭幻?/p>

? ? return wrapper

@count_time? ? # 這實(shí)際就相當(dāng)于解決方法3中的 my_count = count_tiem(my_count)

def my_count():

? ? s = 0

? ? for i in range(10000001):

? ? ? ? s += i

? ? print('sum : ', s)

my_count()

這樣實(shí)現(xiàn)的好處是,定義好了閉包函數(shù)后。只需要通過 @xxx 形式的裝飾器語(yǔ)法,將 @xxx 加到要裝飾的函數(shù)前即可。

使用者在使用時(shí),根本不需要知道被裝飾了。只需要知道原來的函數(shù)功能是什么即可。

這種不改變?cè)泻瘮?shù)功能基礎(chǔ)上,對(duì)函數(shù)進(jìn)行擴(kuò)展的形式,稱為裝飾器。

在執(zhí)行 @xxx 時(shí) ,實(shí)際就是將 原函數(shù)傳遞到閉包中,然后原函數(shù)的引用指向閉包返回的裝飾過的內(nèi)部函數(shù)的引用。

1.8.6 裝飾器的幾種形式

根據(jù)被裝飾函數(shù)定義的參數(shù)和返回值定義形式不同,裝飾器也對(duì)應(yīng)幾種變形。

? 無參無返回值

? ? def setFunc(func):

? ? ? ? def wrapper():

? ? ? ? ? ? print('Start')

? ? ? ? ? ? func()

? ? ? ? ? ? print('End')

? ? ? ? return wrapper

? ? @setFunc

? ? def show():

? ? ? ? print('show')

? ? show()

? 無參有返回值

? ? def setFunc(func):

? ? ? ? def wrapper():

? ? ? ? ? ? print('Start')

? ? ? ? ? ? return func()

? ? ? ? return wrapper

? ? @setFunc? # show = setFunc(show)

? ? def show():

? ? ? ? return 100

? ? print(show() * 100)

? 有參無返回值

? ? def setFunc(func):

? ? ? ? def wrapper(s):

? ? ? ? ? ? print('Start')

? ? ? ? ? ? func(s)

? ? ? ? ? ? print('End')

? ? ? ? return wrapper

? ? @setFunc?

? ? def show(s):

? ? ? ? print('Hello %s' % s)

? ? show('Tom')

? 有參有返回值

? ? def setFunc(func):

? ? ? ? def wrapper(x, y):

? ? ? ? ? ? print('Start')

? ? ? ? ? ? return func(x, y)

? ? ? ? return? wrapper

? ? @setFunc

? ? def myAdd(x, y):

? ? ? ? return? x + y

? ? print(myAdd(1, 2))

1.8.7 萬(wàn)能裝飾器

萬(wàn)能裝飾器的定義:

通過可變參數(shù)和關(guān)鍵字參數(shù)來接收不同的參數(shù)類型定義出來的裝飾器函數(shù)適用于任何形式的函數(shù)。

? def setFunc(func):

? ? ? ? def wrapper(*args, **kwargs):? # 接收不同的參數(shù)

? ? ? ? ? ? print('wrapper context')

? ? ? ? ? ? return func(*args, *kwargs) # 再原樣傳回給被裝飾的函數(shù)

? ? ? ? return wrapper

? ? @setFunc

? ? def show(name, age):

? ? ? ? print(name,age)

? ? show('tom',12)

1.8.8 類實(shí)現(xiàn)裝飾形式

通過類的定義實(shí)現(xiàn)裝飾器形式:

? 在類中通過使用 __init__ 和 __call__方法來實(shí)現(xiàn)

? 通過重寫__init__初始化方法,接收參數(shù),將要被裝飾的函數(shù)傳進(jìn)來并記錄下來(相當(dāng)于外函數(shù)接收參數(shù))

? 通過重寫 __call__ 方法來實(shí)現(xiàn)裝飾內(nèi)容(相當(dāng)于內(nèi)函數(shù)實(shí)現(xiàn)裝飾內(nèi)容)

? @Test? ——》 show = Test(show) show由原來引用函數(shù),裝飾后變成 引用Test裝飾類的對(duì)象

? show() ——》實(shí)際上是仿函數(shù)(是在實(shí)現(xiàn)__call__魔法方法后,將對(duì)象當(dāng)做函數(shù)一樣去使用),即對(duì)象調(diào)用方法實(shí)現(xiàn)了裝飾器

? ? class Test(object):

? ? ? ? # 通過初始化方法,將要被裝飾的函數(shù)傳進(jìn)來并記錄下來

? ? ? ? def __init__(self, func):

? ? ? ? ? ? self.__func = func

? ? ? ? # 重寫 __call__ 方法來實(shí)現(xiàn)裝飾內(nèi)容

? ? ? ? def __call__(self, *args, **kwargs):

? ? ? ? ? ? print('wrapper context')

? ? ? ? ? ? self.__func(*args, **kwargs)

? ? # 實(shí)際通過類的魔法方法call來實(shí)現(xiàn)

? ? @Test? # --> show = Test(show) show由原來引用函數(shù),裝飾后變成引用Test裝飾類的對(duì)象

? ? def show():

? ? ? ? pass

? ? show()? # 對(duì)象調(diào)用方法,實(shí)際上是調(diào)用魔法方法call,實(shí)現(xiàn)了裝飾器

1.8.9 函數(shù)被多個(gè)裝飾器所裝飾(了解)

一個(gè)函數(shù)在使用時(shí),通過一個(gè)裝飾器來擴(kuò)展,可能并不能完成達(dá)到預(yù)期。

Python 中允許一個(gè)裝飾器裝飾多個(gè)函數(shù)和一個(gè)函數(shù)被多個(gè)裝飾器所裝飾。

? 多個(gè)裝飾器的裝飾過程:

? ? ? 從下向上裝飾(即從里往外執(zhí)行),先裝飾函數(shù),然后再向外(向上)一層一層裝飾。

# 裝飾器1

def setFunc1(func):

? ? def wrapper1(*args, **kwargs):

? ? ? ? print('Wrapper Context 1 Start...')

? ? ? ? func(args, kwargs)

? ? ? ? print('Wrapper Context 1 End...')

? ? return wrapper

# 裝飾器2

def setFunc2(func):

? ? def wrapper2(*args, **kwargs):

? ? ? ? print('Wrapper Context 2 Start...')

? ? ? ? func(args, kwargs)

? ? ? ? print('Wrapper Context 2 End...')

? ? return wrapper

#一個(gè)函數(shù)被裝飾了兩次

@setFunc1

@setFunc2

def show(*args, **kwargs):

? ? print('Show Run ...')

show()

程序執(zhí)行結(jié)果 :

Wrapper Context 1 Start...

Wrapper Context 2 Start...

Show Run ...

Wrapper Context 2 End...

Wrapper Context 1 End...

這個(gè)裝飾器的裝飾過程是

從下向上裝飾,即從里往外執(zhí)行,先裝飾函數(shù),然后再一層一層裝飾。

@setFunc2 -> show = setFunc2(show) -> show = setFunc2.wrapper2 @setFunc1 -> show = setFunc1(setFunc2.wrapper2) -> show = setFunc1.wrapper1(setFunc2.wrapper2(show))

1.8.10 裝飾器傳參:

裝飾器在使用過程中,可能需要對(duì)裝飾器進(jìn)行傳參

? 在定義可以傳參的裝飾器閉包時(shí),需要定義三層函數(shù)

? 最外層函數(shù)用來接收裝飾器的參數(shù)

? 中間層用來實(shí)現(xiàn)裝飾器

? 最內(nèi)層用來執(zhí)行具體的裝飾內(nèi)容

? 無論有幾層或者幾個(gè)裝飾器去裝飾已有函數(shù),最終函數(shù)都是引用裝飾器的最內(nèi)層的函數(shù)。

? @xxx(xxx)? 先執(zhí)行傳參 xxx(xxx) ,實(shí)際就是執(zhí)行函數(shù)調(diào)用,得到中間層函數(shù), 與@組合后變成裝飾器形式,再進(jìn)行裝飾

# 定義一個(gè)路由字典

router = {}

# 實(shí)現(xiàn)一個(gè)裝飾器,讓這個(gè)裝飾器來實(shí)現(xiàn)自動(dòng)將 url 和 功能函數(shù)的匹配關(guān)系存到路由字典中

# 接收url參數(shù)

def set_args(args):

? ? # 真正用來去裝飾接收的函數(shù)

? ? def set_func(func):

? ? ? ? # 真正裝飾函數(shù)

? ? ? ? def wrapper(*args, **kwargs):

? ? ? ? ? ? func()

? ? ? ? # 因?yàn)?wrapper 就是指向被裝飾的函數(shù)

? ? ? ? router[args] = wrapper

? ? ? ? return wrapper

? ? return set_func

# 功能函數(shù)

# @set_args('login.html')? ? ? -> @set_func

@set_args('login.html')

def login():

? ? print('Login Run ...')

@set_args('nba.html')

def nba():

? ? print('NBA Run ...')

@set_args('news.html')

def news():

? ? print('News Run ...')

@set_args('11.html')

def double_one():

? ? print('雙十一')

# 模擬的運(yùn)行函數(shù)

def run(url):

? ? # 通過傳入?yún)?shù),也就是訪問地址,來到路由字典中去找到對(duì)應(yīng)的功能函數(shù)

? ? func = router[url]

? ? # 執(zhí)行相應(yīng)的功能函數(shù)

? ? func()

# 模擬請(qǐng)求

run('login.html')

run('nba.html')

run('news.html')

run('11.html')

print(router)

1.8.11 總結(jié):

? 1. 函數(shù)可以像普通變量一樣,做為函數(shù)的參數(shù)或返回值進(jìn)行傳遞

? 2. 函數(shù)內(nèi)部可以定義另外一個(gè)函數(shù),這樣做的目的可以隱藏函數(shù)功能的實(shí)現(xiàn)

? 3. 閉包實(shí)際也是一種函數(shù)定義形式。

? 4. 閉包定義規(guī)則是在外部函數(shù)中定義一個(gè)內(nèi)部函數(shù),內(nèi)部函數(shù)使用外部函數(shù)的變量,并返回內(nèi)部函數(shù)的引用

? 5. Python 中裝飾器就是由閉包來實(shí)現(xiàn)的

? 6. 裝飾器的作用是在不改變現(xiàn)有函數(shù)基礎(chǔ)上,為函數(shù)增加功能。

? 7. 通過在已有函數(shù)前,通過 @閉包函數(shù)名 的形式來給已有函數(shù)添加裝飾器

? 8. 裝飾器函數(shù)根據(jù)參數(shù)和返回值的不同,可細(xì)分為四種定義形式

? 9. 可以通過可變參數(shù)和關(guān)鍵字參數(shù)來實(shí)現(xiàn)能用裝飾器定義形式

? 10. 一個(gè)裝飾器可以為多個(gè)函數(shù)提供裝飾功能,只需要在被裝飾的函數(shù)前加 @xxx 即可

? 11. 通過類也可以實(shí)現(xiàn)裝飾器效果,需要重寫 __init__ 和 __call__ 函數(shù)

? 12. 類實(shí)現(xiàn)的裝飾器在裝飾函數(shù)后,原來的函數(shù)引用不在是函數(shù),而是裝飾類的對(duì)象

? 13. 一個(gè)函數(shù)也可以被多個(gè)裝飾器所裝飾,但是實(shí)際在使用時(shí),并不多見,了解形式即可

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 寫在前面的話 代碼中的# > 表示的是輸出結(jié)果 輸入 使用input()函數(shù) 用法 注意input函數(shù)輸出的均是字...
    FlyingLittlePG閱讀 3,208評(píng)論 0 9
  • 包(lib)、模塊(module) 在Python中,存在包和模塊兩個(gè)常見概念。 模塊:編寫Python代碼的py...
    清清子衿木子水心閱讀 3,907評(píng)論 0 27
  • 秦小破po閱讀 238評(píng)論 0 1
  • 如何學(xué)好英語(yǔ)? 這是老生常談的一個(gè)話題,不斷的聽別人說學(xué)英語(yǔ)有多么重要,也不斷的聽很多人講過如何學(xué)好英語(yǔ),甚至有很...
    帆說凡語(yǔ)閱讀 726評(píng)論 0 2
  • 每次手機(jī)空間不夠,就開始清理垃圾,又需要手動(dòng)清理,結(jié)果就不知道怎么點(diǎn)的,每次清完垃圾總是有很多堆東西會(huì)損失。比...
    忽爾今至閱讀 148評(píng)論 0 0

友情鏈接更多精彩內(nèi)容