一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python中使用語句導入模塊或包的機制研究

Python中使用語句導入模塊或包的機制研究

2020-05-25 09:34Shahriar Tajbakhsh Python

這篇文章主要介紹了Python中使用語句導入模塊或包的機制研究,同時對比了幾種導入包或模塊的語句并簡要說明了這幾種方法之間的幾點優劣,需要的朋友可以參考下

這篇文章討論了Python的from <module> import *和from <package> import *,它們怎么執行以及為什么使用這種語法(也許)是一個壞主意。
從一個模塊導入全部

from <module> import * means意味著“我希望能訪問<module>中我有權限訪問的全部名稱”。例如以下代碼something.py:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# something.py
 
public_variable = 42
_private_variable = 141
 
def public_function():
  print("I'm a public function! yay!")
 
def _private_function():
  print("Ain't nobody accessing me from another module...usually")
 
class PublicClass(object):
  pass
 
class _WeirdClass(object):
  pass

在Python解釋器中,我們可以執行from something import *,然后看到如下的內容:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> from something import *
>>> public_variable
42
>>> _private_variable
...
NameError: name '_private_variable' is not defined
>>> public_function()
"I'm a public function! yay!"
>>> _private_function()
...
NameError: name '_private_function' is not defined
>>> c = PublicClass()
>>> c
<something.PublicClass object at ...>
>>> c = _WeirdClass()
...
NameError: name '_WeirdClass' is not defined

from something import *從something中導入了除了以_開頭名稱外的其他所有名稱,按照規范,_開始的名稱是私有的所以未被導入。
嗯,不是特別糟!還有什么?

上面沒提到__all__是什么。__all__是一個字符串列表,指定了當from <module> import *被使用時,模塊(或者如后文會提到的包)中的哪些符號會被導出。如果我們不定義__all__(我們在上面的something.py就沒定義),import *默認的導入方式是導入除了下劃線(_)開頭的所有名稱。再說一次,編程慣例上下劃線表示一個符號是私有的,不導入是合理的。讓我們來看看在something.py中定義我們自己的__all__會發生什么。
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# something.py
 
__all__ = ['_private_variable', 'PublicClass']
 
# The rest is the same as before
 
public_variable = 42
_private_variable = 141
 
def public_function():
  print("I'm a public function! yay!")
 
def _private_function():
  print("Ain't nobody accessing me from another module...usually")
 
class PublicClass(object):
  pass
 
class _WeirdClass(object):
  pass

現在,我們期望from something import *只會導入_private_variable和PublicClass:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> from something import *
>>> public_variable
42
>>> _private_variable
...
NameError: name '_private_variable' is not defined
>>> public_function()
"I'm a public function! yay!"
>>> _private_function()
...
NameError: name '_private_function' is not defined
>>> c = PublicClass()
>>> c
<something.PublicClass object at ...>
>>> c = _WeirdClass()
...
NameError: name '_WeirdClass' is not defined

包是怎樣的呢?

當從一個包中導入全部時,__all__的做法和模塊基本一樣,不過它處理的是包中的模塊(而不是把模塊中的名都導入)。所以當我們使用from <package> import *.時__all__說明了所有需要被導入當前命名空間的模塊。

不同之處在于,如果你在一個包的__init__.py里面沒有聲明__all__,from <package> import *語句不會導入任何東西(這個說法也不全對,正確的說法在此)
但是,這有什么不好?

繼續讀之前,在你的Python解釋器中,執行import this,再讀一遍Python之禪(在你孩子每晚睡前也要讀給他們)。

    明確比含糊要好。

from <module> import * 是不明確的。它沒告訴我們我們正在導入什么或者我們把什么帶入當前命名空間了。更好的做法是顯式地導入我們需要的全部名稱。這種方式下,讀者(非??赡苁俏磥淼哪阕约海┚筒粫Щ笥谀愦a中使用的一個變量/方法/類/其他東西是哪兒來的,這也告訴了我們下一點:

    可讀性很重要

即使你需要導入很多東西,一個一個顯式地導入也更清楚。使用PEP 328:
 

?
1
2
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
  LEFT, DISABLED, NORMAL, RIDGE, END)

你現在就能明確知道你的命名空間里有什么,使用ctrl+f能很快地告訴你它們是哪兒來的。

同時,你還總是要承擔模塊/包作者更改list內容(加/減東西)的風險。也就是下面兩者之一:

    作者從__all__里刪除了一個字符串。如果你的代碼使用了那個名字,你的代碼就會報出NameError的錯誤,并且很難發現為什么。
    作者在__all__里加入了很多東西。你也許不需要這些增加的內容,所以你只是讓這些你不關心的東西占滿了你的命名空間。他們甚至在你不注意的時候會替代其他同名內容。

當然,有時候從模塊或者包中導入全部內容是有用的。不過,這么做之前三思。從我的經驗來看,這么做通常只是因為懶。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本男男gaygays| 国产真实一区二区三区 | 热久久最新网址 | 天天爽天天干天天操 | nxgx在线观看国产中文 | 国产欧美一区二区成人影院 | 午夜AV亚洲一码二中文字幕青青 | 国产重口老太伦 | 图片专区亚洲欧美另类 | 国产成人免费观看在线视频 | 性欧美videofree中文字幕 | 天海翼黄色三级 | 小莹的性荡生活45章 | 亚洲精品久久久打桩机 | 久久er国产精品免费观看2 | 男生操女生动态图 | 久久国产精品永久免费网站 | 日本成熟 | 处女摘花| 女人又色又爽又黄 | 亚洲国产成人精品 | 欧美国产在线视频 | 精品视频手机在线观看免费 | 亚洲 日韩 国产 中文视频 | 免费理伦片手机在线播放 | 国产麻豆剧果冻传媒观看免费视频 | 亚洲精品丝袜在线一区波多野结衣 | 国产精品视频免费观看 | 大又大又粗又爽女人毛片 | 精品一区二区高清在线观看 | 亚洲风情无码免费视频 | 亚洲成片在线看 | 操国产美女 | yy8090韩国日本三理论免费 | 女暴露狂校园裸露小说 | 国产精品视频久久 | 91香蕉国产在线观看免费永久 | 免费一级欧美片在线观看 | 精品欧美| 人人擦 | 欧美乱妇高清无乱码视频在线 |