Python的from import和import的區別?

我剛開始學習Python,對於import和from import我覺得應該是有區別的,但是在網上搜了一圈,還是沒有解答我的疑惑。

ps:我是使用的python3.5版本。

例如datetime:

from datetime import datetime
print(datetime.now())

就可以執行,但是用import就不行:

import datetime
print(datetime.now())

報錯:AttributeError: module "datetime" has no attribute "now"

import datetime.datetime
print(datetime.now())

報錯:ImportError: No module named "datetime.datetime"; "datetime" is not a package

是不是datetime只能用from import而不能用import?

from import 和 import有什麼區別?


兩個import語義有差異

import datetime
print(datetime.datetime.now())

是引入整個datetime包

from datetime import datetime
print(datetime.now())

是只引入datetime包里的datetime類

所以import之後前者是datetime這個包可見 後者是datetime.datetime這個類可見


from import : 從車裡把礦泉水拿出來,給我

import : 把車給我

題主可能困惑於,為什麼會有人讓自己把「車裡面的車」拿出來,因為這是倆不同的車啊,裡面那個是玩具車


我想樓主容易搞錯的原因是用了datetime的包。

datetime的包里還有個重名的datetime的子項,在這個子項下才有now的函數。

因為有個重名的子項,所以初學者可能會搞混。

把樓主的疑問換個包來回答樓主應該能清晰點:

下面三個都是正確的寫法,調用的是os包里path子項的join函數,作用是將路徑相加成一個完整路徑:

from os.path import join
print(join("C:\windows", "system32"))

import os
print(os.path.join("C:\windows", "system32"))

import os.path
print(os.path.join("C:\windows", "system32"))

輸出全是:

C:windowssystem32


你雖然import datetime,但是now是datetime模塊下datetime類的now方法,所以你要寫成datetime.datetime.now啊……

from datetime import datetime是因為從datetime里引入了datetime類,引入的並不是這個模塊而是這個類,自然是datetime.now


import xx導入模塊對於模塊中的函數,每次調用需要「模塊.函數」來用。

from xx import fun 直接導入模塊中某函數,直接fun()就可用。

告訴你大法:from xx import * 該模塊中所有函數可以直接使用。

====================2016-12-11=========更新===========

覺得之前的回答不夠全面,再補充下吧!

題主應該把import xx,xx不只想像成一個單文件,它還可能是一個文件夾(所謂的包),

文件夾裡面還有子文件夾。你的問題是一級文件夾與二級文件夾同名而已。你是調用深度不夠。

舉一反三多幾次就明白了。


一般情況下盡量使用import a,此時訪問B時,可以通過a.B的形式。

有節制的使用from a import B,這樣可以直接使用B。

避免使用from a import *,這種方法會污染命名空間,而且不能直觀的顯示導入哪些對象


你有一個工具箱,箱子里有剪刀,有鉗子,有螺絲刀等等。

現在你想擰螺絲。

然後你一個操作是:從 工具箱 里拿 螺絲刀,然後用 螺絲刀 擰螺絲 ( from import)。

別一個操作是: 拿了 工具箱 ,沒打開呢,直接就有 擰螺絲 的功能( import )

所以在真正去擰螺絲時候,一個直接拿過來就能用,一個需要聲明是用工具箱里的螺絲刀


import Module # 引入模塊

from Module import Other # 引入模塊中的類、函數或者變數

from Module import * # 引入模塊中的所有『公開』成員

PS:當有一個包名為pname時,其內部 *.py 文件的模塊名就是 pname.* 也就是說模塊名中包含了 Package包 這個概念。

其區別就是:

第一個:引入的模塊(假如是 mdemo )會自動生成一個『對象『以模塊名命名,然後就可以通過這個『對象』(mdemo)獲取該模塊裡面的類、函數或變數等...

第二個:引入模塊中的Other(這裡的Other就是模塊中定義的成員)成員,調用時就可以省略 模塊名。

第三個:這種情況如果上面的第二個弄懂的話就不難理解了,其意思就是引入模塊中所有"公開"的成員。

---------鑒於題主的提問可以快速套用上面的分析:

from datetime import datetime

# 引入 datetime 模塊中的 datetime 類,然後就可以通過datetime這個類調用now() 方法了

# 即,內部可以通過datetime.now()來調用

import datetime

# 引入datetime 模塊,然後通過這個模塊來調用模塊中的類datetime和類datetime中的方法now()

# 即:內部可以通過datetime.datetime.now()來調用

也就是說,有一個模塊datetime,這個模塊中有一個類datetime,在這個類中有一個方法now()

我們可以驗證上面這句話是否正確:

我們可以通過查看python默認查找模塊位置,一個個打開看下是否有datetime這個模塊

----以上純屬我的理解,如有錯誤,多多指教


假如是import的話,後面大概是要這樣導入的

比如說 import urllib2

這個時候後你要是調用包裡面的方法就需要帶上包名

比如說 urllib2.urlopen()

而,假如你是只想導入這個包里的某個方法(又或者全部)

from urllib2 import urlopen

這樣的話以後就可以直接使用urlopen方法了

urlopen()

總結一下,這兩個的區別給我的感覺就是假如你需要明確這個方法從哪個包來就只用import,這樣看起來會更容易理解,而,假如你不需要讓代碼看起來盡量簡單那麼就使用from import 這樣就不需要前綴包名,代碼看起來也比較清爽,

至於你的datetime很容易知道,你的包名和其中一個方法同名,你以為引入了datetime方法,而實際卻只導入了包,所以使用方法應該是datetime.datetime.now()

小白一枚,如有什麼問題還請大家多多指教?? ( ′? ? `? ) ??


from datetime import datetime

這行命令相當於,校長說:高三二班的 李偉出來,站在我面前

import datetime

這行命令相當於,校長說:高三二班,都站在我面前

from datetime import datetime 中 調用 datetime.now() 成功是因為:

這個命令相當於,校長說:: 李偉,現在是幾點? 因為就一個李偉站在他面前,能確定是哪個李偉。

import datetime 調用 datetime.now() 失敗是因為:

這個命令相當於,校長說:: 李偉,現在是幾點? 可是校長面前,站了整個高三二班,沒法知道是哪個李偉??


from module import Something

module是一個模塊,說白了是一個文件,比如 datetime.py文件。

Something是模塊的一個具體對象,可以是函數,可以是變數,可以是類。

Python標準庫中有些東西容易糊弄住新手,比如你說的datetime模塊,datetime模塊中有一個與datetime.py文件同名的類 &,now是它的一個靜態方法,可以不用生成實例直接以Class.method()的方式調用。

為什麼datetime模塊中要定義一個同名的類糊弄人,這個我也不清楚,可能門親吻了腦子。Python的標準庫中還有幾個同樣不規範的模塊。


解決兩個問題即可搞清楚兩者的異同

1、import後面可以跟什麼

1)可以跟文件名、目錄名(當然最好理解為包名),這樣就類似include 這樣的語句,將文件加入而已。

import example1.example1_1 #這裡就是將example1/example1_1.py 引入

或者可以使用from

from example1 import example1_1

從這裡可以看出,如果從引入文件的角度出發,from後面的內容和import後面的內容相似,都是文件名或者目錄名。這種方式,的確不容易判斷example1_1到底是一個文件、目錄或是example1_1()這樣一個方法。

調用的時候,必須按照import後面的包的完整結構進行調用

example1_1.say_hello()

2)可以跟類名、方法名

from example1.example1_1 import say_hello #從目錄、包或文件中引入一個方法

say_hello() #可以直接調用;

from example1.example1_1 import User #從目錄、包或者文件中引入一個類

User("name"="xiaoming")#可以直接調用

2、from後面可以跟什麼

只能是文件、目錄或者包。

推薦的寫法,使用「from 包名 import 方法/類」然後直接調用方法或者類的書寫方式。

當然,如果import只是將整個文件包進來,僅作文件的連接,兩種方式就沒有什麼區別。


當你用from datetime import datetime時,是從datetime包中導入datetime類,用的時候直接可以引用datetime。import datetime的話是導入整個datetime包,引用包里的類時要用datetime.xxx


就好比如說,朋友有一把槍,你只想要他的槍去打獵,那就用import,import是把對方的槍給要過來,注意,是槍這個是整體;

可如果你是想要幾發子彈裝逼,那就沒必要用槍了,用槍挺麻煩的,還不會使用,一不小心走火就悲劇了,所以這個時候你需要從槍里把子彈拿出來,注意,是需要裡面的子彈,但是子彈在槍里,我不摸槍拿不到子彈呀,你朋友也不能用槍把子彈打出來,也就意味著,必須從槍里把子彈拿出來。

所以,from 槍 import 子彈,這個意思就是我需要槍里的子彈裝逼。


梳理一下我剛剛理解的內容

  • import Module:相當於只是給該Module做一個聲明?如果要用的話,還是得Module.function()這樣使用,因為其內部的成員,函數之類並沒有被【實際裝載】到編輯器或內存?(不知道我這樣表述是否準確)
  • from Module import function:相當於將Module中的function()部分裝載到了內存中或編輯器中?所以能直接function()調用?
  • from Module import *:相當於將Module中的所有內容全都轉載到了內存或編輯器中,不僅能直接用function()還可以直接用function1(),function2().....?


剛學Python,剛開始也挺疑惑的,學習了一些有點了解。說的不對的話希望有人指正。

總的來說,import的作用是把其他模塊,也就是其他人寫的 .py文件導入到你寫的代碼中來,引用別人寫好的函數或者是方法、類。

先說一下題主說的from datetime import datetime中的兩個datetime其實是不一樣的,一個表示的是模塊,也就是 .py 文件,另一個表示的是這個模塊中的函數或方法。為了不混淆這兩個,我下面的是自己假設的一個模塊和其中的兩個方法。定義一個模塊名字叫test 其中裡邊有兩個函數分別是 test 1 和test 2 。然後在其他文件中使用這兩個函數的方法有下邊的形式:

1 使用import test將整個模塊全部導入到你文件中

使用該方法的時候,該模塊中整個都在你的文件中了,裡邊的函數都可以盡情的調用了。但是這個時候你調用函數的時候的方式是 模塊名.函數名()例如調用test 1

import test
test.test1()

2 使用from test import * 將整個模塊調入,但是在使用的時候就比上邊的方便多了,調用方式就是直接用 函數名() 例如調用test 1

from test import *
test1()

3 如果只使用模塊中的部分函數 就不需要全部導入整個模塊 這時候的方法就是 from test import

test1

from test import test1
test1()

函數直接調用就可以了 前邊不用加模塊名。


copy from 作者:蘇格拉底

https://www.zhihu.com/question/38857862/answer/230127705

蘇格拉底的回答切中了要點,但是需要點實例來佐證,

先總結:推薦的寫法,使用「from 包名 import 方法/類」然後直接調用方法或者類的書寫方式。

當然,如果import只是將整個文件包進來,僅作文件的連接,兩種方式就沒有什麼區別。

首先,如圖-2,圖-3,datetime是一個.py文件,其中有三個類是datetime,所以當用圖-1中的方法會有如下結果:

from datetime import datetime as d1 #成功
import datetime.datetime as d2 #失敗並提示ModuleNotFoundError: No module named "datetime.datetime"; "datetime" is not a package

而如圖-4,matplotlib中style是一個文件夾,所以此時import和from import形式都是如圖-1一樣的效果。

from matplotlib import style as s1 #成功
import matplotlib.style as s2 #成功

圖-1

圖-2

圖-3

圖-4


因為一個模塊裡面 可以有函數,也可以有類,也可以有常量等等(其他的東西我暫時還不知道...)。

這個類裡面,又可以有函數。

你引入的datetime模塊 裡面 有 一個類 和 datetime模塊 名字是一樣的,就是datetime類

而這個now() 函數是在datetime類里的,而不是直接在datetime模塊下的。

所以你當你引入(import) datetime 這個模塊,是把整個模塊引入了。所以這個時候調用這個now()函數的方式是這樣的:

import datetime
print( datetime.datetime.now() )

而當你單獨從(from) datetime 這個模塊 引入(import) datetime 這個類 時。調用的方式是這樣的:

from datetime import datetime
print( datetime.now() )

如有錯誤請指正

以上


樓上基本都回答完了,但是需要注意的是:

1.導入模塊會創建新的模塊命名空間,在調用導入模塊中的函數時會引用該模塊的命名空間。

2.from ** import **是將模塊里的具體定義載入到當前命名空間。

3.除非python已經用得666了,請盡量不要使用from module import * 。


樓主是不是從Java之類的語言轉過來的?Java的import看上去和Python里不太一樣,Java里沒有import一個包名的概念(或者說極少用),而在Python里這種用法較常見。所以會覺得怎麼明明已經import了一個東西,使用起來的時候還要加上前綴,其實你把它們都看成是命名空間就好了。解釋器也需要足夠的信息才能唯一確定一個類或者方法的具體調用是指哪,人確定不了的,它也確定不了


推薦閱讀:

python有什麼類似特性(或者是解釋型語言特性)?
新手遇到笨辦法學python第13題?
Python中locale如何配置setlocale()的參數?
你看好 Python 3 嗎?
如何用python網路爬蟲求兩個城市間鐵路距離呢?

TAG:Python | Python3x | Python入門 |