国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【Python3】Python模塊與包的導(dǎo)入

CoyPan / 2385人閱讀

摘要:模塊與包的導(dǎo)入一模塊導(dǎo)入定義模塊,是一個文件,以結(jié)尾,包含了對象定義和語句。使用模塊還可以避免函數(shù)名和變量名沖突。特別注意的是自定義的模塊名不應(yīng)該與系統(tǒng)內(nèi)置模塊重名。包是由一系列模塊組成的集合。模塊的導(dǎo)入使用語句。

【Python3】Python模塊與包的導(dǎo)入 一、模塊導(dǎo)入 1. 定義

Python 模塊(Module),是一個 Python 文件,以 .py 結(jié)尾,包含了 Python 對象定義和Python語句。

模塊讓你能夠有邏輯地組織你的 Python 代碼段。

把相關(guān)的代碼分配到一個模塊里能讓你的代碼更好用,更易懂。

模塊能定義函數(shù),類和變量,模塊里也能包含可執(zhí)行的代碼。

包括:內(nèi)置模塊,自定義模塊,第三方模塊;

2. 作用

最大的好處是大大提高了代碼的可維護(hù)性。其次,編寫代碼不必從零開始。當(dāng)一個模塊編寫完畢,就可以被其他地方引用。我們在編寫程序的時候,也經(jīng)常引用其他模塊,包括Python內(nèi)置的模塊和來自第三方的模塊。

使用模塊還可以避免函數(shù)名和變量名沖突。相同名字的函數(shù)和變量完全可以分別存在不同的模塊中,因此,我們自己在編寫模塊時,不必考慮名字會與其他模塊沖突。但是也要注意,盡量不要與內(nèi)置函數(shù)名字沖突。

3. import

模塊定義好后,我們可以使用 import 語句來引入模塊,語法如下:

import module1[, module2[,... moduleN]

例:

#spam.py
print("from the spam.py")

money=1000

def read1():
    print("spam->read1->money",money)

def read2():
    print("spam->read2 calling read")
    read1()

def change():
    global money
    money=0

導(dǎo)入模塊

import spam #只在第一次導(dǎo)入時才執(zhí)行spam.py內(nèi)代碼,此處的顯式效果是只打印一次"from the spam.py",當(dāng)然其他的頂級代碼也都被執(zhí)行了,只不過沒有顯示效果.
執(zhí)行結(jié)果:
 from the spam.py

注:模塊可以包含可執(zhí)行的語句和函數(shù)的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導(dǎo)入import語句時才執(zhí)行(import語句是可以在程序中的任意位置使用的,且針對同一個模塊很import多次,為了防止你重復(fù)導(dǎo)入,python的優(yōu)化手段是:第一次導(dǎo)入后就將模塊名加載到內(nèi)存了,后續(xù)的import語句僅是對已經(jīng)加載大內(nèi)存中的模塊對象增加了一次引用,不會重新執(zhí)行模塊內(nèi)的語句)

import導(dǎo)入模塊干的事:
1.產(chǎn)生新的名稱空間
2.以新建的名稱空間為全局名稱空間,執(zhí)行文件的代碼
3.拿到一個模塊名spam,指向spam.py產(chǎn)生的名稱空間

測試一:money與spam.money不沖突

#測試一:money與spam.money不沖突
#test.py
import spam 
money=10
print(spam.money)

"""
執(zhí)行結(jié)果:
from the spam.py
1000
"""

測試二:read1與spam.read1不沖突

#測試二:read1與spam.read1不沖突
#test.py
import spam
def read1():
    print("========")
spam.read1()

"""
執(zhí)行結(jié)果:
from the spam.py
spam->read1->money 1000
"""

測試三:執(zhí)行spam.change()操作的全局變量money仍然是spam中的money

#測試三:執(zhí)行spam.change()操作的全局變量money仍然是spam中的
#test.py
import spam
money=1
spam.change()
print(money)

"""
執(zhí)行結(jié)果:
from the spam.py
1
"""

as,為模塊名起別名

 import spam as sm  #sm為spam的別名
 print(sm.money)

例:

為已經(jīng)導(dǎo)入的模塊起別名的方式對編寫可擴(kuò)展的代碼很有用,假設(shè)有兩個模塊xmlreader.py和csvreader.py,它們都定義了函數(shù)read_data(filename):用來從文件中讀取一些數(shù)據(jù),但采用不同的輸入格式。可以編寫代碼來選擇性地挑選讀取模塊,例如

if file_format == "xml":
     import xmlreader as reader
elif file_format == "csv":
    import csvreader as reader
data=reader.read_date(filename)

在一行導(dǎo)入多個模塊

import sys,os,re
4. From…import
from modname import name1[, name2[, ... nameN]]

要導(dǎo)入模塊 fib 的 fibonacci 函數(shù),使用如下語句:

from fib import fibonacci

這個聲明不會把整個 fib 模塊導(dǎo)入到當(dāng)前的命名空間中,它只會將 fib 里的 fibonacci 單個引入到執(zhí)行這個聲明的模塊的全局符號表。

from... import..導(dǎo)入模塊干的事:

1.產(chǎn)生新的名稱空間
2.以新建的名稱空間為全局名稱空間,執(zhí)行文件的代碼
3.直接拿到就是spam.py產(chǎn)生的名稱空間中名字

#測試一:導(dǎo)入的函數(shù)read1,執(zhí)行時仍然回到spam.py中尋找全局變量money
#test.py
from spam import read1
money=1000
read1()
"""
執(zhí)行結(jié)果:
from the spam.py
spam->read1->money 1000
"""

#測試二:導(dǎo)入的函數(shù)read2,執(zhí)行時需要調(diào)用read1(),仍然回到spam.py中找read1()
#test.py
from spam import read2
def read1():
    print("==========")
read2()

"""
執(zhí)行結(jié)果:
from the spam.py
spam->read2 calling read
spam->read1->money 1000
"""

但如果當(dāng)前有重名read1或者read2,那么會有覆蓋效果。

#測試三:導(dǎo)入的函數(shù)read1,被當(dāng)前位置定義的read1覆蓋掉了
#test.py
from spam import read1
def read1():
    print("==========")
read1()
"""
執(zhí)行結(jié)果:
from the spam.py
==========
"""

需要特別強(qiáng)調(diào)的一點是:python中的變量賦值不是一種存儲操作,而只是一種綁定關(guān)系,如下:

from spam import money,read1
money=100 #將當(dāng)前位置的名字money綁定到了100
print(money) #打印當(dāng)前的名字
read1() #讀取spam.py中的名字money,仍然為1000

"""
from the spam.py
100
spam->read1->money 1000
"""

from ... import ...
優(yōu)點:方便,不用加前綴
缺點:容易跟當(dāng)前文件的名稱空間沖突

from ... import...也支持as和導(dǎo)入多模塊

from spam import read1 as read

from spam import (read1,
                  read2,
                  money)

from spam import *
把spam中所有的不是以下劃線(_)開頭的名字都導(dǎo)入到當(dāng)前位置,大部分情況下我們的python程序不應(yīng)該使用這種導(dǎo)入方式,因為*你不知道你導(dǎo)入什么名字,很有可能會覆蓋掉你之前已經(jīng)定義的名字。而且可讀性極其的差,在交互式環(huán)境中導(dǎo)入時沒有問題。

from spam import * #將模塊spam中所有的名字都導(dǎo)入到當(dāng)前名稱空間
print(money)
print(read1)
print(read2)
print(change)

"""
執(zhí)行結(jié)果:
from the spam.py
1000



"""

__all__來控制*(用來發(fā)布新版本)
在spam.py中新增一行

__all__=["money","read1"] #這樣在另外一個文件中用from spam import *就這能導(dǎo)入列表中規(guī)定的兩個名字

name
spam.py當(dāng)做腳本執(zhí)行,__name__="__main__"

spam.py當(dāng)做模塊導(dǎo)入,__name__=模塊名

作用:用來控制.py文件在不同的應(yīng)用場景下執(zhí)行不同的邏輯

#fib.py

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=" ")
        a, b = b, a+b
    print()

def fib2(n):   # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

執(zhí)行

#python fib.py 
python fib.py 50 #在命令行 
5.模塊的搜索路徑

模塊的查找順序是:內(nèi)存中已經(jīng)加載的模塊->內(nèi)置模塊->sys.path路徑中包含的模塊

python解釋器在啟動時會自動加載一些模塊,可以使用sys.modules查看,在第一次導(dǎo)入某個模塊時(比如spam),會先檢查該模塊是否已經(jīng)被加載到內(nèi)存中(當(dāng)前執(zhí)行文件的名稱空間對應(yīng)的內(nèi)存),如果有則直接引用

如果沒有,解釋器則會查找同名的內(nèi)建模塊,如果還沒有找到就從sys.path給出的目錄列表中依次尋找spam.py文件。

特別注意的是:自定義的模塊名不應(yīng)該與系統(tǒng)內(nèi)置模塊重名。

在初始化后,python程序可以修改sys.path,路徑放到前面的優(yōu)先于標(biāo)準(zhǔn)庫被加載。

注意:搜索時按照sys.path中從左到右的順序查找,位于前的優(yōu)先被查找,sys.path中還可能包含.zip歸檔文件和.egg文件,python會把.zip歸檔文件當(dāng)成一個目錄去處理,

#首先制作歸檔文件:zip module.zip foo.py bar.py

import sys
sys.path.append("module.zip")
import foo,bar

#也可以使用zip中目錄結(jié)構(gòu)的具體位置
sys.path.append("module.zip/lib/python")

注意:windows下的路徑不加r開頭,會語法錯誤

windows下的路徑不加r開頭,會語法錯誤
sys.path.insert(0,r"C:UsersAdministratorPycharmProjectsa")
二、包的導(dǎo)入 1. 定義

包是一種通過使用‘.模塊名’來組織python模塊名稱空間的方式。

無論是import形式還是from...import形式,凡是在導(dǎo)入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關(guān)于包才有的導(dǎo)入語法。.的左邊必須是包;

包是一個分層次的文件目錄結(jié)構(gòu),它定義了一個由模塊及子包,和子包下的子包等組成的 Python 的應(yīng)用環(huán)境。簡單來說,包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內(nèi)容可以為空。__int__.py用于標(biāo)識當(dāng)前文件夾是一個包。

包是由一系列模塊組成的集合。模塊是處理某一類問題的函數(shù)和類的集合。

例:

glance/                   #Top-level package

├── __init__.py      #Initialize the glance package

├── api                  #Subpackage for api

│   ├── __init__.py

│   ├── policy.py

│   └── versions.py

├── cmd                #Subpackage for cmd

│   ├── __init__.py

│   └── manage.py

└── db                  #Subpackage for db

    ├── __init__.py

    └── models.py

文件內(nèi)容

#文件內(nèi)容

#policy.py
def get():
    print("from policy.py")

#versions.py
def create_resource(conf):
    print("from version.py: ",conf)

#manage.py
def main():
    print("from manage.py")

#models.py
def register_models(engine):
    print("from models.py: ",engine)
2. import

在使用一個模塊中的函數(shù)或類之前,首先要導(dǎo)入該模塊。模塊的導(dǎo)入使用import語句。

調(diào)用模塊的函數(shù)或類時,需要以模塊名作為前綴。

import導(dǎo)入文件時,產(chǎn)生名稱空間中的名字來源于文件,import 包,產(chǎn)生的名稱空間的名字同樣來源于文件,即包下的__init__.py,導(dǎo)入包本質(zhì)就是在導(dǎo)入該文件

例:
在與包glance同級別的文件中測試

import glance.db.models
glance.db.models.register_models("mysql") 

凡是在導(dǎo)入時帶點的,點的左邊都必須是一個包。

3.from ... import ...

如果不想在程序中使用前綴符,可以使用from…import…語句將模塊導(dǎo)入。

需要注意的是from后import導(dǎo)入的模塊,必須是明確的一個不能帶點,否則會有語法錯誤,如:from a import b.c是錯誤語法

例:

在與包glance同級別的文件中測試

from glance.db import models
models.register_models("mysql")

from glance.db.models import register_models
register_models("mysql")

執(zhí)行的文件的當(dāng)前路徑就是sys.path

import sys
print(sys.path)

注意:

1.關(guān)于包相關(guān)的導(dǎo)入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什么位置,在導(dǎo)入時都必須遵循一個原則:凡是在導(dǎo)入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如item.subitem.subsubitem,但都必須遵循這個原則。

2.對于導(dǎo)入后,在使用時就沒有這種限制了,點的左邊可以是包,模塊,函數(shù),類(它們都可以用點的方式調(diào)用自己的屬性)。

3.對比import item 和from item import name的應(yīng)用場景:
如果我們想直接使用name那必須使用后者。

4. __init__.py文件

不管是哪種方式,只要是第一次導(dǎo)入包或者是包的任何其他部分,都會依次執(zhí)行包下的__init__.py文件(我們可以在每個包的文件內(nèi)都打印一行內(nèi)容來驗證一下),這個文件可以為空,但是也可以存放一些初始化包的代碼。

5.from glance.api import *

從包api中導(dǎo)入所有,實際上該語句只會導(dǎo)入包api下__init__.py文件中定義的名字,我們可以在這個文件中定義__all___:

#在__init__.py中定義
x=10

def func():
    print("from api.__init.py")

__all__=["x","func","policy"]

此時我們在于glance同級的文件中執(zhí)行from glance.api import *就導(dǎo)入__all__中的內(nèi)容(versions仍然不能導(dǎo)入)。

6.絕對導(dǎo)入和相對導(dǎo)入

最頂級包glance是寫給別人用的,然后在glance包內(nèi)部也會有彼此之間互相導(dǎo)入的需求,這時候就有絕對導(dǎo)入和相對導(dǎo)入兩種方式:

絕對導(dǎo)入:以glance作為起始

相對導(dǎo)入:用.或者..的方式最為起始(只能在一個包中使用,不能用于不同目錄內(nèi))

例:我們在glance/api/version.py中想要導(dǎo)入glance/cmd/manage.py

在glance/api/version.py

#絕對導(dǎo)入
from glance.cmd import manage
manage.main()

#相對導(dǎo)入
from ..cmd import manage
manage.main()

測試結(jié)果:注意一定要在于glance同級的文件中測試

from glance.api import versions 

注意:可以用import導(dǎo)入內(nèi)置或者第三方模塊(已經(jīng)在sys.path中),但是要絕對避免使用import來導(dǎo)入自定義包的子模塊(沒有在sys.path中),應(yīng)該使用from... import ...的絕對或者相對導(dǎo)入,且包的相對導(dǎo)入只能用from的形式。

7.多帶帶導(dǎo)入包

多帶帶導(dǎo)入包名稱時不會導(dǎo)入包中所有包含的所有子模塊,如

#在與glance同級的test.py中
import glance
glance.cmd.manage.main()

"""
執(zhí)行結(jié)果:
AttributeError: module "glance" has no attribute "cmd"

"""

解決方法:

#glance/__init__.py
from . import cmd
 
#glance/cmd/__init__.py
from . import manage

執(zhí)行:

#在于glance同級的test.py中
import glance
glance.cmd.manage.main()

千萬別問:__all__不能解決嗎,__all__是用于控制from...import *

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/38628.html

相關(guān)文章

  • Python與家國天下

    摘要:正如儒家經(jīng)典所闡述修身齊家治國平天下。除此之外,模塊還有如下最基本的屬性在一個模塊的全局空間里,有些屬性是全局起作用的,稱之為全局變量,而其它在局部起作用的屬性,會被稱為局部變量。 導(dǎo)讀:Python貓是一只喵星來客,它愛地球的一切,特別愛優(yōu)雅而無所不能的 Python。我是它的人類朋友豌豆花下貓,被授權(quán)潤色與發(fā)表它的文章。如果你是第一次看到這個系列文章,那我強(qiáng)烈建議,請先看看它寫的前...

    姘擱『 評論0 收藏0
  • Python與家國天下

    摘要:正如儒家經(jīng)典所闡述修身齊家治國平天下。除此之外,模塊還有如下最基本的屬性在一個模塊的全局空間里,有些屬性是全局起作用的,稱之為全局變量,而其它在局部起作用的屬性,會被稱為局部變量。 導(dǎo)讀:Python貓是一只喵星來客,它愛地球的一切,特別愛優(yōu)雅而無所不能的 Python。我是它的人類朋友豌豆花下貓,被授權(quán)潤色與發(fā)表它的文章。如果你是第一次看到這個系列文章,那我強(qiáng)烈建議,請先看看它寫的前...

    felix0913 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<