1. 程式人生 > 其它 >import java.awt.event.*什麼意思_學了半天,import 到底在幹啥?

import java.awt.event.*什麼意思_學了半天,import 到底在幹啥?

技術標籤:import java.awt.event.*什麼意思

哈嘍~小夥伴們我又來啦~
Python憑什麼就那麼好用呢?

毫無疑問,大量現成又好用的內建/第三方庫功不可沒。

那我們是怎麼使用它們的呢?

噢,對了~是用的import xxx這個語句。

之所以會有此一問,也是之前有一次使用PyCharm進行開發時(又)踩了個坑……

ae0a53535083ef920643d29a3f346c8b.png

廢話少說,先講問題

像下面這樣一個專案結構:

Projetc_example
|-- A
   |-- alpha.py
   |-- beta.py
|-- B
    |-- theta.py
|-- main
    |-- main.py

假設要在main.py

中匯入theta.py

# main/main.py
from B import theta

顯然會導致我們所不希望的問題,即Python不知道要到哪裡去找這個名為B的模組(包是一種特殊的模組):

Traceback (most recent call last):
  File "main/main.py", line 1, in <module>
    from B import theta
ModuleNotFoundError: No module named 'B'

可是這就奇了怪了,為啥同樣的程式碼,在PyCharm裡執行就是好的了呢?

11c6c65cd71c8a4ee7363e24144ecbbc.png

import的查詢路徑

於是我們不辭艱辛,上下求索,原來在Python中,import語句實際上封裝了一系列過程。

1. 查詢是否已匯入同名模組

首先,Python會按照import xxx中指定的包名,到sys.modules中查詢當前環境中是否已經存在相應的包——不要奇怪為什麼都沒有匯入sys這個模組就有sys.modules了。

sys是Python內建模組,也就是親兒子,匯入只是意思一下,讓我們這樣的外人在匯入的環境中也可以使用相關介面而已,實際上相應的資料對Python而言從始至終都是透明的。

a4220903f2b77d9b95d2e6388a3244a4.png

我們可以匯入sys檢視一下這個物件的具體內容(節省篇幅,做省略處理):

>>> import sys
>>> sys.modules
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, ...'re': <module 're' from 'E:AnacondaAnacondalibre.py'>, ...}

這些就都是Python一開始就已經載入好的模組,也就是安裝好Python之後,只要一執行環境中就已經就緒的模組——只是作為外人的我們還不能直接拿過來用,得跟Python報備一聲:“欸,我要拿您兒子來用了嗨~”

很容易可以發現,sys.modules中列出來的已載入模組中存在明顯的不同,前面的很多模組顯得很乾淨,而後面的很多模組都帶有from yyy'的字樣,並且這個yyy看起來還像是一個路徑。

這就關係到我們接下來要講的步驟了。

2. 在特定路徑下查詢對應模組

前面我們講到了,當我們匯入某個模組時,Python先會去查詢sys.modules,看其中是否存在同名模組,查到了那當然皆大歡喜,Python直接把這個模組給我們用就好了,畢竟兒子那麼多,借出去賺點外快也是好事兒不是?

可問題在於:那要是沒找到呢?

這顯然是一個很現實的問題。畢竟資源是有限的,Python不可能把你可能用到的所有模組全都一股腦給載入起來,否則這樣男上加男加男加男……誰也頂不住啊不是(大霧

534cad49b02229799b8d8e5e952d936d.png


於是乎就有人給Python出了個主意:那你等到要用的時候,再去找他說他是你兒子唄

Python:妙哇~

57c57ea268e243752dfb4819dd58e784.png


有了這個思路,Python就指定了幾家特定的酒樓,說:“凡是去消費的各位,都可以給我當兒子。”

就這樣,一些本來不是Python親兒子的人,出於各種原因聚集到了這幾家酒樓,以僱傭兵的身份隨時準備臨時稱為Python的兒子。

這可就比周文王開局就收100個義子優雅多了,養家餬口的壓力也就沒那麼大了(Python:什麼?我的親兒子都不止100個?你說什麼?聽不見啊——

ee9a8cbc68f1d5a3371c0cb52d27b467.png


回到正經的畫風來——

實際上,在Python中,sys.path維護的就是這樣一個py交易的結果~~(誒?好像莫名發現了什麼),其中儲存的內容就是這幾家“指定酒樓”,也就是當Python遇到不認識的兒子~~模組時,就會去實地查詢的路徑。

我們也可以打印出來看看具體內容:

>>> sys.path
['', 'E:AnacondaAnacondapython37.zip', 'E:AnacondaAnacondaDLLs', 'E:AnacondaAnacondalib', 'E:AnacondaAnaconda', 'E:AnacondaAnacondalibsite-packages', 'E:AnacondaAnacondalibsite-packageswin32', 'E:AnacondaAnacondalibsite-packageswin32lib', 'E:AnacondaAnacondalibsite-packagesPythonwin']

大體上就是安裝環境時配置的一些包所在路徑,其中第一個元素代表當前所執行指令碼所在的路徑。

也正是因此,我們可以在同一個目錄下,大大方方地呼叫其他模組。

3. 將模組與名字繫結

找到相應的非親生模組還沒完,載入了包還得為它分配一個指定的名字,我們才能在指令碼中使用這個模組。

當然多數時候我們感知不到這個過程,因為我們就是一個import走天下:

import sys
import os
import requests

這個時候我們指定的模組名,實際上也是指定的稍後用來呼叫相應模組的物件名稱。

換個更明顯的:

import requests as req

如果這個時候只使用了第二種方式來匯入requests這個模組,那麼很顯然在之後的程式流程中,我們都不能使用requests這個名字來呼叫它而應當使用req

這就是Python匯入過程中的名稱繫結,本質上與正常的賦值沒有太大區別,載入好了一個物件之後,然後為這個物件賦一個指定的變數名。

當然即使是已經載入好的模組,我們也可以利用這個名稱繫結的機制為它們取別名,比如:

>>> import sys
>>> import sys as sy
>>> sys.path
['', 'E:AnacondaAnacondapython37.zip', 'E:AnacondaAnacondaDLLs', 'E:AnacondaAnacondalib', 'E:AnacondaAnaconda', 'E:AnacondaAnacondalibsite-packages', 'E:AnacondaAnacondalibsite-packageswin32', 'E:AnacondaAnacondalibsite-packageswin32lib', 'E:AnacondaAnacondalibsite-packagesPythonwin']
>>> sy.path
['', 'E:AnacondaAnacondapython37.zip', 'E:AnacondaAnacondaDLLs', 'E:AnacondaAnacondalib', 'E:AnacondaAnaconda', 'E:AnacondaAnacondalibsite-packages', 'E:AnacondaAnacondalibsite-packageswin32', 'E:AnacondaAnacondalibsite-packageswin32lib', 'E:AnacondaAnacondalibsite-packagesPythonwin']
>>> sys == sy
True

問題解決

好了,上面就是對Python匯入機制的大致介紹,但是說了半天,我們的問題還沒有解決:在專案中如何簡潔地跨模組匯入其他模組?

在使用PyCharm的時候倒是一切順遂,因為PyCharm會自動將專案的根目錄加入到匯入的搜尋路徑,也就是說像下面這樣的專案結構,在任意模組中都可以很自然地通過import A匯入模組A,用import B匯入模組B。

Projetc_example
|-- A
   |-- alpha.py
   |-- beta.py
|-- B
    |-- theta.py
|-- main
    |-- main.py

但是在非IDE環境中呢?或者說就是原生的Python環境中呢?

很自然地我們就會想到:那就手動把專案根目錄加入到sys.path中去嘛。說起來也跟PyCharm做的事沒差呀

可以,貧道看你很有悟性,不如跟我去學修仙吧

所以我們就通過sysos兩個模組七搞八搞(這兩個模組以前有過介紹,不再贅述)——

噔噔噔噔——好使了

# Peoject_example/A/alpha.py
print("name: " + __name__)
print("file: " + __file__)

def al():
    print("Importing alpha succeeded.")

main.py中則加入一個邏輯,在sys.path中增加一個專案根目錄:

import os
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

import A.alpha


A.alpha.al()

# name: A.alpha
# file: *Project_exampleAalpha.py
# Importing alpha succeeded.

大功告成,風緊扯呼~

總結

本文藉由一個易現問題引出對Python匯入機制的介紹,實際上限於篇幅,匯入機制只是做了一個概覽,具體的內容還要更加複雜。本文講到的這三步則適用於比較常見的情形,瞭解了這三步也足以應付很多問題了。更多內容還是留待大家自行探索,當然後續也可能會有文章進一步講解——誰知道呢哈哈~~(又挖坑了)~~

ノBye~