99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)大數(shù)據(jù)時(shí)代告別菜鳥,一文學(xué)會(huì)Python模塊(有深度)
告別菜鳥,一文學(xué)會(huì)Python模塊(有深度)
2021-01-25
收藏

來(lái)源:麥?zhǔn)寰幊?

作者:麥?zhǔn)?

Python必備核心技能 - 模塊module(內(nèi)容超詳細(xì),舉例說(shuō)明很容易懂)

Python模塊和包是和變量,函數(shù),類同等重要的基礎(chǔ)的基礎(chǔ)。因?yàn)樗鼈兪荘ython組織程序的方式。掌握不好,你很難學(xué)習(xí)和理解新的知識(shí),會(huì)處處碰壁。是掌握Python必備的核心技能。

在硬核Python私教班課程中,我把所有關(guān)鍵技能總結(jié)為Python 36技,模塊和包是其中之一。如果你想快速系統(tǒng)的學(xué)習(xí)Python,建立辦公自動(dòng)化,數(shù)據(jù)分析等實(shí)戰(zhàn)技能,需要有專業(yè)老師指導(dǎo)你解決問(wèn)題,可以考慮麥?zhǔn)逅浇陶n,物美價(jià)廉。有興趣咨詢maishu1024。

本文詳細(xì)講解了:

  • 模塊和概念;
  • 創(chuàng)建自己的模塊;
  • Python模塊的查找路徑;
  • import語(yǔ)句的各種用法;
  • 創(chuàng)建模塊和核心技巧;

模塊化編程是指將編程任務(wù)分解為單獨(dú)的,較小的,更易于管理的子任務(wù)或模塊的過(guò)程。然后可以像構(gòu)建模塊

一樣將各個(gè)模塊拼湊在一起以創(chuàng)建更大的應(yīng)用程序。

程序模塊化代碼有幾個(gè)優(yōu)點(diǎn):

  • 簡(jiǎn)單性:模塊通常只關(guān)注問(wèn)題的一個(gè)相對(duì)較小的部分,而不是關(guān)注整個(gè)問(wèn)題。如果你只關(guān)注單個(gè)模塊,
  • 那么只有一個(gè)更小的問(wèn)題域需要處理。這使得開發(fā)更容易,更不容易出錯(cuò)。
  • 可維護(hù)性:分成多個(gè)小文件,修改的時(shí)候只要修改相關(guān)的文件就行了。而且可以多人協(xié)作,同時(shí)修改而不會(huì)產(chǎn)生沖突。
  • 可重用性:?jiǎn)蝹€(gè)模塊中定義的功能可以被應(yīng)用程序的其他部分輕松地重用(通過(guò)適當(dāng)定義的接口)。這減少了重復(fù)代碼。
  • 作用域:模塊通常會(huì)定義一個(gè)單獨(dú)的命名空間,這有助于避免程序不同區(qū)域中的名字發(fā)生沖突。(Python禪的信條之一是:命名空間是一個(gè)很棒的發(fā)明)

函數(shù),模塊和包都是Python中促進(jìn)代碼模塊化的機(jī)制。

1.Python模塊:概述

在Python中定義模塊的方式有三種:

  • 用Python編寫的模塊,我們寫的主要是這一類模塊
  • 用C語(yǔ)言編寫模塊,并在運(yùn)行時(shí)動(dòng)態(tài)加載模塊,例如re(正則表達(dá)式)模塊。這種模塊看不到源代碼。
  • 包含在解釋器中的內(nèi)置模塊,比如itertools模塊。

在這三種情況下,訪問(wèn)模塊內(nèi)容的方式都是相同的: 使用import語(yǔ)句。

本文重點(diǎn)主要放在用Python編寫的模塊上。用Python編寫的模塊很酷的一點(diǎn)是,它很容易。

你所需要做的就是創(chuàng)建一個(gè)包含合法Python代碼的文件,然后給該文件一個(gè)后綴名為.py的名稱。就是這樣!不需要特殊的語(yǔ)法或魔法。你就創(chuàng)建了一個(gè)模塊。

例如,假設(shè)你創(chuàng)建了一個(gè)名為mod.py的文件,其中包含以下內(nèi)容:

s = "這是我的第一個(gè)模塊,我是麥?zhǔn)?,喜歡請(qǐng)關(guān)注我." a = [100200300] def foo(arg):    
 print(f'arg = {arg}') class Foo:     pass 

mod.py中定義了幾個(gè)對(duì)象:

  • s (一個(gè)字符串)
  • a (一個(gè)列表)
  • foo() (一個(gè)函數(shù))
  • Foo (一個(gè)類)

假設(shè)mod.py保存在你電腦上的某一個(gè)位置,這些對(duì)象可以通過(guò)如下方式導(dǎo)入模塊來(lái)訪問(wèn):

>>> import mod >>> print(mod.s)
這是我的第一個(gè)模塊,我是麥?zhǔn)?,喜歡請(qǐng)關(guān)注我. >>> mod.a
[100200300] >>> mod.foo(['你好''我好''大家好'])
arg = ['你好''我好''大家好'] >>> x = mod.Foo() >>> x
<mod.Foo object at 0x03C181F0>

2.模塊搜索路徑

繼續(xù)上面的例子,讓我們看看當(dāng)Python執(zhí)行語(yǔ)句時(shí)會(huì)發(fā)生什么:

import mod

當(dāng)解釋器執(zhí)行上面的import語(yǔ)句時(shí),它會(huì)依次去下面的目錄搜索mod.py,搜索不到就報(bào)錯(cuò):

  • 運(yùn)行代碼的目錄,如果使用交互式Python,則為當(dāng)前目錄
  • 環(huán)境變量PYTHONPATH中的目錄。
  • 安裝Python時(shí)配置的與安裝相關(guān)的目錄列表

可以通過(guò)sys.path來(lái)得到所有搜索路徑。

>>> import sys >>> sys.path
['''C:\Users\maishu\Documents\Python\doc''C:\Python36\Lib\idlelib', 'C:\Python36\python36.zip',
 'C:\Python36\DLLs''C:\Python36\lib', 'C:\Python36''C:\Python36\lib\site-packages']

注意:sys.path 和你的python環(huán)境有關(guān)。上面的代碼在你的電腦上看起來(lái)會(huì)有些許不同。

因此,要確保找到你的模塊,你需要執(zhí)行以下操作之一:

  • 如果是交互環(huán)境,把mod.py保存到執(zhí)行命令的當(dāng)前目錄
  • 將mod.py所在目錄放到PYTHONPATH環(huán)境變量中
    • 或者:把mod.py文件放到已經(jīng)存在PYTHONPATH中的某一個(gè)目錄
  • 把mod.py放在python安裝相關(guān)的目錄中

實(shí)際上還有一個(gè)額外的選項(xiàng):你可以將模塊文件放在你選擇的任何目錄中,然后臨時(shí)修改sys.path,以便包含該目錄。例如,

在這種情況下,你可以把mod.py放在目錄C:Usersmaishu中,然后使用以下代碼:

>>> sys.path.append(r'C:Usersmaishu')
>>> sys.path
['''C:\Users\maishu\Documents\Python\doc''C:\Python36\Lib\idlelib', 'C:\Python36\python36.zip',
 'C:\Python36\DLLs''C:\Python36\lib', 'C:\Python36''C:\Python36\lib\site-packages''C:\Users\maishu']
>>> import mod

一旦模塊被導(dǎo)入,你就可以通過(guò)模塊的__file__屬性來(lái)確定它被找到的位置:

>>> import mod >>> mod.__file__ 'C:\Users\maishu\mod.py' >>> import re >>> re.__file__ 'C:\Python36\lib\re.py' 

3.import語(yǔ)句

最簡(jiǎn)單的形式是上面所示的:

import <module_name>

請(qǐng)注意,這種簡(jiǎn)單的形式只是引用了模塊本身,模塊內(nèi)的東西并沒有直接引入,不能直接用名字訪問(wèn),而要通過(guò)模塊.變量的形式。

模塊會(huì)創(chuàng)建一個(gè)單獨(dú)的名稱空間,防止和別的模塊發(fā)生沖突。這樣就能以模塊名作為前綴,通過(guò)點(diǎn)訪問(wèn)模塊內(nèi)的東西,如下所示。

在下列import語(yǔ)句之后,mod被引入到本文件中。因此,可以引用mod:

>>> import mod >>> mod
<module 'modfrom 'C:\Users\maishu\Documents\Python\doc\mod.py'> 

但是s和foo仍然在屬于mod內(nèi)部的變量和函數(shù),不能直接使用:

>>> s NameError: name 's' is not defined >>> foo('quux') NameError: name 'foo' is not defined 

必須加上mod前綴才可以:

>>> mod.s 'If Comrade Napoleon says it, it must be right.' >>> mod.foo('quux')
arg = quux

幾個(gè)用逗號(hào)分隔的模塊可以在一個(gè)import語(yǔ)句中指定:

import <module_name>[, <module_name> ...]

from <module_name> import <name(s)>

import語(yǔ)句的另一種形式允許將模塊中的單個(gè)對(duì)象直接導(dǎo)入:

from <module_name> import <name(s)>

執(zhí)行上面的語(yǔ)句后, 可以在不使用前綴的調(diào)用者環(huán)境中被引用:

>>> from mod import s, foo >>> s '這是我的第一個(gè)模塊,我是麥?zhǔn)?,喜歡請(qǐng)關(guān)注我.' >>> foo('你好')
arg = 你好 >>> from mod import Foo >>> x = Foo() >>> x
<mod.Foo object at 0x02E3AD50>

因?yàn)檫@種形式的導(dǎo)入將對(duì)象名稱直接引入當(dāng)前文件,任何已經(jīng)存在的具有相同名稱的對(duì)象都將被覆蓋:

>>> a = ['foo''bar''baz'] >>> a
['foo''bar''baz'] >>> from mod import a >>> a
[100200300]

甚至可以一下子不加區(qū)別地從一個(gè)模塊中導(dǎo)入所有內(nèi)容:

from <module_name> import *

這將把模塊中的所有對(duì)象的名稱引入當(dāng)前文件,但不包括以下劃線(_)開頭的內(nèi)容。

例如:

>>> from mod import *
>>> s '這是我的第一個(gè)模塊,我是麥?zhǔn)?,喜歡請(qǐng)關(guān)注我.' >>> a
[100200300] >>> foo
<function foo at 0x03B449C0> >>> Foo
<class 'mod.Foo'> 

在大規(guī)模的項(xiàng)目中并不推薦這樣做。這有一點(diǎn)危險(xiǎn),因?yàn)檫@會(huì)在引入全部名稱。除非你對(duì)它們都很了解,并且確信不會(huì)有沖突,

否則你很有可能會(huì)無(wú)意中覆蓋現(xiàn)有的變量。然而,當(dāng)你只是為了測(cè)試或?qū)W習(xí)目的而使用交互式解釋器時(shí),此語(yǔ)法非常方便,

因?yàn)樗梢宰屇憧焖僭L問(wèn)模塊所提供的所有內(nèi)容,而無(wú)需大量輸入。

from <module_name> importas <alt_name>

也可以導(dǎo)入單獨(dú)的對(duì)象,并且給它設(shè)置一個(gè)別名:

from <module_name> import <name> as <alt_name>[, <name> as <alt_name> …]

這使得可以直接將名稱引入,但避免與之前存在的名稱沖突:

>>> s = 'foo' >>> a = ['foo''bar''baz'] >>> from mod import s as string, a as alist >>> s 'foo' >>
string '這是我的第一個(gè)模塊,我是麥?zhǔn)?,喜歡請(qǐng)關(guān)注我.' >>> a
['foo''bar''baz'] >>> alist
[100200300]

import <module_name> as <alt_name>

你也可以用這種方式導(dǎo)入整個(gè)模塊:

import <module_name> as <alt_name>
>>> import mod as my_module >>> my_module.a
[100200300] >>> my_module.foo('qux')
arg = qux

模塊內(nèi)容也可以從函數(shù)中導(dǎo)入。在這種情況下,模塊只有在函數(shù)被調(diào)用才會(huì)被導(dǎo)入:

>>def bar():
...     from mod import foo
...     foo('corge')
... >>> bar()
arg = corge

然而,Python3不允許從函數(shù)內(nèi)部使用import *:

>>def bar():
...     from mod import *
... SyntaxError: import * only allowed at module level 

最后,帶有except ImportError子句的try語(yǔ)句可以用來(lái)防止失敗的導(dǎo)入嘗試:

>>> try:
...     # Non-existent module ...     import baz
... except ImportError:
...     print('Module not found')
...

Module not found
>>> try:
...     # Existing module, but non-existent object ...     from mod import baz
... except ImportError:
...     print('Object not found in module')
...

Object not found in module

4.dir()函數(shù)

內(nèi)置函數(shù)dir()返回一個(gè)模塊中定義的所有名稱列表(函數(shù),全局變量等)。如果沒有參數(shù),它會(huì)在當(dāng)前局部符號(hào)表中生成一個(gè)按字母排序的名稱列表:

>>> dir()
['__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__'] >>> qux = [12345] >>> dir()
['__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__''qux'] >>class Bar(): ...     pass
... >>> x = Bar() >>> dir()
['Bar''__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__''qux''x']

請(qǐng)注意上面對(duì)dir()的第一次調(diào)用是如何列出幾個(gè)已經(jīng)在命名空間中的名稱的。當(dāng)定義了新的名稱(qux, Bar, x)時(shí),它們會(huì)出現(xiàn)在后續(xù)的dir()調(diào)用中。

這對(duì)于確定import語(yǔ)句到底給命名空間添加了什么是很有用的:

>>> dir()
['__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__'] >>> import mod >>> dir()
['__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__''mod'] >>> mod.s 'If 
Comrade Napoleon says it, it must be right.' >>> mod.foo([123])
arg = [123] >>> from mod import a, Foo >>> dir()
['Foo''__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__''a''mod'] >>> a
[100200300] >>> x = Foo() >>> x
<mod.Foo object at 0x002EAD50> >>> from mod import s as string >>> dir()
['Foo''__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__''a''mod'
'string''x'] >>> string 'If Comrade Napoleon says it, it must be right.' 

當(dāng)給dir()一個(gè)模塊名的參數(shù)時(shí),dir()列出在該模塊中定義的名稱:

>>> import mod >>> dir(mod)
['Foo''__builtins__''__cached__''__doc__''__file__''__loader__', '__name__''__package__''__spec__''a''foo''s']
>>> dir()
['__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__'] >>> from mod import *
>>> dir()
['Foo''__annotations__''__builtins__''__doc__''__loader__''__name__', '__package__''__spec__''a''foo''s']

5.將模塊作為腳本執(zhí)行

任何包含模塊的.py文件本質(zhì)上也是一個(gè)Python腳本,沒有任何理由不能像Python腳本那樣執(zhí)行它。

下面是mod.py的定義:

mod.py

s = "If Comrade Napoleon says it, it must be right." a = [100200300] def foo(arg):     print(f'arg = {arg}') class Foo:     pass 

這可以作為一個(gè)腳本運(yùn)行:

C:UsersmaishuDocuments>python mod.py C:UsersmaishuDocuments>

沒有錯(cuò)誤,所以它顯然是有效的。當(dāng)然,這不是很有趣。就像它寫的那樣,它只定義對(duì)象。它不會(huì)對(duì)它們做任何事情,也不會(huì)生成任何輸出。

讓我們修改一下上面的Python模塊,這樣當(dāng)它作為腳本運(yùn)行時(shí)就會(huì)生成一些輸出:

mod.py

s = "If Comrade Napoleon says it, it must be right." a = [100200300] def foo(arg): 
    print(f'arg = {arg}') class Foo:     pass print(s)
print(a)
foo('quux')
x = Foo()
print(x)

現(xiàn)在應(yīng)該更有趣了:

C:UsersmaishuDocuments>python mod.py If Comrade Napoleon says it, it must be right.
 [100, 200, 300] arg = quux <__main__.Foo object at 0x02F101D0> 

不幸的是,現(xiàn)在它也會(huì)在作為模塊導(dǎo)入時(shí)生成輸出:

>>> import mod If Comrade Napoleon says it, it must be right.
[100200300] arg = quux
<mod.Foo object at 0x0169AD50>

這可能不是你想要的。模塊在導(dǎo)入時(shí)通常不會(huì)生成輸出。

如果能夠區(qū)分文件是作為模塊加載的,還是作為獨(dú)立腳本運(yùn)行的,不是很好嗎?

這當(dāng)然是可以做到的!

當(dāng).py文件作為模塊導(dǎo)入時(shí),Python將特殊的變量__name__設(shè)置為模塊的名稱。但是,如果一個(gè)文件作為一個(gè)獨(dú)立的腳本運(yùn)行,

__name__被設(shè)置為字符串'__main__'?;谶@個(gè),你可以辨別哪種情況是在運(yùn)行時(shí)發(fā)生的,并相應(yīng)地改變行為:

mod.py

s = "If Comrade Napoleon says it, it must be right." a = [100200300] def foo(arg):
     print(f'arg = {arg}') class Foo:     pass if (__name__ == '__main__'):
    print('Executing as standalone script')
    print(s)
    print(a)
    foo('quux')
    x = Foo()
    print(x)

現(xiàn)在,如果你作為一個(gè)腳本運(yùn)行,你會(huì)得到輸出:

C:UsersmaishuDocuments>python mod.py
Executing as standalone script
If Comrade Napoleon says it, it must be right.
[100, 200, 300]
arg = quux
<__main__.Foo object at 0x03450690>

但如果你以模塊的形式導(dǎo)入,不會(huì)有輸出:

>>> import mod >>> mod.foo('grault')
arg = grault

為了測(cè)試模塊中包含的功能,模塊通常被設(shè)計(jì)為能夠作為獨(dú)立的腳本運(yùn)行。這被稱為單元測(cè)試。例如,

假設(shè)你已經(jīng)創(chuàng)建了一個(gè)包含階乘函數(shù)的模塊fact.py,如下所示:

fact.py

def fact(n):     return 1 if n == 1 else n * fact(n-1) if (__name__ == '__main__'):
    import sys
    if len(sys.argv) > 1:
        print(fact(int(sys.argv[1])))

可以將該文件視為一個(gè)模塊,并導(dǎo)入fact()函數(shù):

>>> from fact import fact >>> fact(6) 720 

但它也可以通過(guò)在命令行中傳遞一個(gè)整數(shù)參數(shù)來(lái)獨(dú)立運(yùn)行,以進(jìn)行測(cè)試:

C:UsersmaishuDocuments>python fact.py 6 720 

6.重新加載模塊

為了提高效率,一個(gè)模塊在每次解釋器會(huì)話中只加載一次。這對(duì)于函數(shù)和類定義來(lái)說(shuō)很好,它們通常構(gòu)成模塊內(nèi)容的大部分。

但是模塊也可以包含可執(zhí)行語(yǔ)句,通常用于初始化。請(qǐng)注意,這些語(yǔ)句只會(huì)在第一次導(dǎo)入模塊時(shí)執(zhí)行。

考慮下面的mod.py文件:

mod.py

a = [100, 200, 300] print('a =', a)
>>> import mod
a = [100200300] >>> import mod >>> import mod >>> mod.a
[100200300]

print()只有在第一次導(dǎo)入模塊時(shí)執(zhí)行,不會(huì)在后續(xù)導(dǎo)入中執(zhí)行。

如果你對(duì)模塊做了更改并需要重新加載它,你需要重新啟動(dòng)解釋器或使用模塊importlib中的重載函數(shù): reload()

>>> import mod
a = [100200300] >>> import mod >>> import importlib >>> importlib.reload(mod)
a = [100200300]
<module 'modfrom 'C:\Users\maishu\Documents\Python\doc\mod.py'> 

數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }