日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python多级目录import_你真的会用Python模块与工具包吗?

發(fā)布時(shí)間:2023/12/2 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python多级目录import_你真的会用Python模块与工具包吗? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在開(kāi)發(fā)過(guò)程中,我們無(wú)法把所有代碼、資源都放在同一個(gè)文件中。因此,模塊導(dǎo)入在編碼中是很常見(jiàn)的。無(wú)論是C++、Java,還是Python、Go。

可以把不同功能、不同模塊進(jìn)行分離,當(dāng)使用的時(shí)候,可以通過(guò)import關(guān)鍵字在一個(gè)模塊中使用另外一個(gè)模塊提供的能力,這能夠大大提升代碼的開(kāi)發(fā)效率。

尤其是對(duì)于Python這種對(duì)于模塊、工具包依賴較強(qiáng)的編程語(yǔ)言,這一點(diǎn)更為突出。

模塊導(dǎo)入,這一點(diǎn)在Python中最為常見(jiàn)的東西對(duì)于很多人來(lái)說(shuō)都不屑一顧,但是,你真的徹底理解Python中的import嗎?

我可以斷言,絕大多數(shù)Python開(kāi)發(fā)人員只是使用,卻不知所以然。

本文,就來(lái)詳細(xì)、徹底的介紹一下Python模塊導(dǎo)入的使用。

模塊與工具包

模塊(modules)和工具包(packages)這2個(gè)概念首當(dāng)其沖,經(jīng)常被Python開(kāi)發(fā)者混為一談。

雖然,二者有很多相同之處,但是還是存在一定差異。因此,要想徹底理解import,首先就需要理解模塊與工具包的異同點(diǎn)。

模塊

Python官網(wǎng)對(duì)于模塊的定義如下:

模塊具有一個(gè)包含任意Python對(duì)象的命名空間,通常用作Python代碼組織單位的對(duì)象。

實(shí)際上,一個(gè)模塊通常對(duì)應(yīng)一個(gè).py文件,模塊的真正功能是可以將其導(dǎo)入到其他代碼中,并重復(fù)使用,例如:

>>> import math
>>> math.pi
3.141592653589793

第一行代碼,通過(guò)import把math模塊導(dǎo)入到代碼中,通過(guò)math.pi來(lái)調(diào)用pi這一屬性。

這里需要注意,這里寫(xiě)的math.pi不僅是單純的pi,它還把math充當(dāng)所有屬性保持統(tǒng)一的命名空間。命名空間對(duì)于保持代碼的可讀性和組織性非常有用。

你可以利用 dir來(lái)查看命名空間的內(nèi)容:

>>> import math
>>> dir()
['__annotations__', '__builtins__', ..., 'math']

>>> dir(math)
['__doc__', ..., 'nan', 'pi', 'pow', ...]

除了上述直接導(dǎo)入,我們還可以導(dǎo)入模塊下特定的部分:

>>> from math import pi
>>> pi
3.141592653589793

>>> math.pi
NameError: name 'math' is not defined

請(qǐng)注意,這里對(duì)比于前一種方式已經(jīng)發(fā)生了一些轉(zhuǎn)變。這里的pi是放置在全局命名空間內(nèi),而不是math的命名空間內(nèi)。

同樣,首先看一下Python官網(wǎng)對(duì)工具包的定義:

一個(gè)Python模塊,可以包含子模塊或遞歸地包含子包。從技術(shù)上講,包是具有__path__屬性的Python模塊。

從定義上可以看出,包仍然是模塊。但是,它們還是有一定的區(qū)別。

從編碼上來(lái)講,Python包需要在目錄下創(chuàng)建一個(gè)名為_(kāi)_init__.py的文件。

導(dǎo)入模塊時(shí),通常不會(huì)導(dǎo)入子模塊和子包,但是,你可以通過(guò)添加__init__.py來(lái)將需要導(dǎo)入的子模塊和子包囊括進(jìn)去。

絕對(duì)導(dǎo)入與相對(duì)導(dǎo)入

from ... import ...這種導(dǎo)入當(dāng)時(shí)在代碼中經(jīng)常會(huì)遇到,假如,我們有如下工程:

world/

├── africa/
│ ├── __init__.py
│ └── zimbabwe.py

├── europe/
│ ├── __init__.py
│ ├── greece.py
│ ├── norway.py
│ └── spain.py

└── __init__.py

當(dāng)想要導(dǎo)入africa時(shí)可以這樣:

from world import africa

也可以這樣:

from . import africa

那么這里面的**點(diǎn)(.)**代表什么含義?

這里的點(diǎn)(.)就是一種相對(duì)導(dǎo)入,你可以理解為從當(dāng)前包中導(dǎo)入africa

相反,絕對(duì)導(dǎo)入語(yǔ)句中,需要明確命名當(dāng)前包:

from world import africa

在編碼過(guò)程中,你可以選擇絕對(duì)導(dǎo)入,也可以選擇相對(duì)導(dǎo)入。只不過(guò),PEP 8風(fēng)格指南中,建議使用絕對(duì)導(dǎo)入。

Python導(dǎo)入路徑

這是一個(gè)需要重點(diǎn)理解的問(wèn)題,很多開(kāi)發(fā)者從接觸Python開(kāi)始就是用PyCharm,它對(duì)于導(dǎo)入路徑已經(jīng)進(jìn)行了默認(rèn)的配置,因此,開(kāi)發(fā)者很難遇到無(wú)法導(dǎo)入的問(wèn)題。

但是,當(dāng)切換到VS Code、Sublime這些需要較多自行配置的開(kāi)發(fā)工具之后,會(huì)發(fā)現(xiàn)無(wú)法導(dǎo)入,或者因?yàn)閷?dǎo)入工具包帶來(lái)的調(diào)用錯(cuò)誤問(wèn)題。

Python是如何找到它要導(dǎo)入的模塊和包的?

你可以試著輸出sys.path,你會(huì)發(fā)現(xiàn)輸出列表中主要包含如下3個(gè)部分的位置:

  • 當(dāng)前腳本目錄
  • PYTHON_PATH環(huán)境變量
  • 其他與安裝相關(guān)的目錄

通常情況下,Python將對(duì)列表進(jìn)行從頭開(kāi)發(fā)遍歷,從每個(gè)位置中尋找給定的模塊,直到第一個(gè)匹配為止

由于腳本所在目錄始終被排在列表的第一位,因此,導(dǎo)入模塊時(shí)它會(huì)首先從當(dāng)前目錄下進(jìn)行尋找。

所以,一定不要把自己的代碼文件名稱(chēng)與工具包重名。

例如,當(dāng)前目錄有一個(gè)名為math.py的文件:

# math.py

def double(number):
return 2 * number

這時(shí)候,你導(dǎo)入可以按照預(yù)期工作:

>>> import math
>>> math.double(3.14)
6.28

但是,它已經(jīng)覆蓋了Python自帶的math標(biāo)準(zhǔn)庫(kù)。如果我們誤認(rèn)為導(dǎo)入的是標(biāo)準(zhǔn)math模塊,去調(diào)用pi、sqrt這些方法,則會(huì)報(bào)錯(cuò):

>>> math.pi
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'math' has no attribute 'pi'>>> math'math' from 'math.py'>

因此,為了避免這個(gè)問(wèn)題,一定小心自己開(kāi)發(fā)代碼文件的命名。

創(chuàng)建并安裝本地工具包

在Python開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)用到pip安裝來(lái)自PyPI倉(cāng)庫(kù)的工具包,它可以用于全局的工程項(xiàng)目。

除了從倉(cāng)庫(kù)下載安裝工具包,還可以自行在本地創(chuàng)建工具包,并完成安裝。

創(chuàng)建本地安裝包只需要?jiǎng)?chuàng)建setup.cfg和setup.py兩個(gè)項(xiàng)目就行:

# setup.cfg

[metadata]
name = local_structure
version = 0.1.0

[options]
packages = structure

# setup.py

import setuptools

setuptools.setup()

這里的版本名稱(chēng)和版本號(hào)可以自行選擇。

然后,可以執(zhí)行下方命令,把創(chuàng)建的安裝包安裝到本地:

$ python -m pip install -e .

導(dǎo)入樣式

為了保持代碼的可讀性和可維護(hù)性,PEP 8提出了一些針對(duì)模塊導(dǎo)入的規(guī)則:

  • 將導(dǎo)入放在文件的頂部
  • 每個(gè)導(dǎo)入要分行
  • 將導(dǎo)入分組:首先是標(biāo)準(zhǔn)庫(kù)導(dǎo)入,然后是第三方導(dǎo)入,最后是本地應(yīng)用程序或庫(kù)導(dǎo)入
  • 在每個(gè)組中按字母順序排序?qū)?/li>
  • 絕對(duì)導(dǎo)入優(yōu)先于相對(duì)導(dǎo)入
  • 避免使用通配符導(dǎo)入from module import *
# Standard library imports
import sys
from typing import Dict, List

# Third party imports
import feedparser
import html2text

# Reader imports
from reader import URL

資源導(dǎo)入

除了模塊和工具包,代碼開(kāi)發(fā)過(guò)程中,還會(huì)經(jīng)常用到外部資源包,針對(duì)外部資源包的導(dǎo)入,可以使用importlib.resources。

它是Python 3.7中的標(biāo)準(zhǔn)模塊,使用它有2點(diǎn)好處:

  • 使得導(dǎo)入方式更加一致
  • 可以更輕松地訪問(wèn)其他包中的資源文件

例如,

>>> from importlib import resources
>>> with resources.open_text("books", "alice_in_wonderland.txt") as fid:
... alice = fid.readlines()

動(dòng)態(tài)導(dǎo)入

Python是一門(mén)動(dòng)態(tài)語(yǔ)言,這也是它的主要特點(diǎn)之一。

動(dòng)態(tài)語(yǔ)言使得你可以在程序運(yùn)行的時(shí)候做很多事情,可以添加屬性、重新定義方法、更改模塊的文檔字符串。

例如,通過(guò)修改print()函數(shù),使它不做任何操作:

>>> print("Hello dynamic world!")
Hello dynamic world!

>>> # Redefine the built-in print()
>>> print = lambda *args, **kwargs: None

>>> print("Hush, everybody!")
>>> # Nothing is printed

在上述示例中,print函數(shù)就被匿名函數(shù)重新定義了。

除了這種方法,還有更為易用的動(dòng)態(tài)導(dǎo)入方式,就是利用importlib。

先來(lái)看一段示例,

# docreader.py

import importlib

module_name = input("Name of module? ")
module = importlib.import_module(module_name)
print(module.__doc__)

import_module()返回可以綁定到任何變量的模塊對(duì)象。然后,您可以將該變量視為常規(guī)導(dǎo)入的模塊。

$ python docreader.py
Name of module? math
This module is always available. It provides access to the
mathematical functions defined by the C standard.

$ python docreader.py
Name of module? csv
CSV parsing and writing.

在每種情況下,該模塊都是通過(guò)動(dòng)態(tài)導(dǎo)入的import_module()。

周期性導(dǎo)入

如果兩個(gè)或者多個(gè)模塊互相導(dǎo)入時(shí),就會(huì)發(fā)生周期性導(dǎo)入。

例如,有兩個(gè)模塊yin.py和yang.py:

# yin.py

print(f"Hello from yin")
import yang
print(f"Goodbye from yin")

# yang.py

print(f"Hello from yang")
import yin
print(f"Goodbye from yang")

嘗試在交互式命令行下導(dǎo)入yin時(shí)會(huì)發(fā)生下面情況:

>>> import yin
Hello from yin
Hello from yang
Goodbye from yang
Goodbye from yin

有些同學(xué)會(huì)疑惑,這樣互相導(dǎo)入,難道不會(huì)無(wú)限循環(huán)下去嗎?

這得益于Python的模塊緩存機(jī)制,在導(dǎo)入yin之后,會(huì)首先把它加入到緩存中,后續(xù)再導(dǎo)入,會(huì)先去參考緩存區(qū)域,避免無(wú)限循環(huán)。


推薦閱讀

或許,這是最強(qiáng)大的一款Python GUI工具

8個(gè)小技巧教你提升Python代碼質(zhì)量

5款最強(qiáng)且免費(fèi)的Python IDE

福利

最近我花費(fèi)了半個(gè)月的時(shí)間,整理了1份理論+實(shí)踐的計(jì)算機(jī)視覺(jué)入門(mén)教程,這或許是你見(jiàn)過(guò)最好的一份CV教程之一。獨(dú)家打造、完全免費(fèi),需要的同學(xué)可以掃碼添加我的個(gè)人微信,發(fā)送“CV”獲取~

總結(jié)

以上是生活随笔為你收集整理的python多级目录import_你真的会用Python模块与工具包吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。