如何理解Python中包的引入
Python的from import *和from import *,它們的功能都是將包引入使用,但是它們是怎么執(zhí)行的以及為什么使用這種語法呢?
從一模塊導入全部功能
from import * means意味著“我希望能訪問中我有權限訪問的全部名稱”。例如以下代碼something.py:
# 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解釋器中,我們可以執(zhí)行from something import *,然后看到如下的內容:
>>> 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中導入了除了以_開頭名稱外的其他所有名稱,按照規(guī)范,_開始的名稱是私有的所以未被導入。
上面沒提到__all__是什么。__all__是一個字符串列表,指定了當from import *被使用時,模塊(或者如后文會提到的包)中的哪些符號會被導出。如果我們不定義__all__(我們在上面的something.py就沒定義),import *默認的導入方式是導入除了下劃線(_)開頭的所有名稱。再說一次,編程慣例上下劃線表示一個符號是私有的,不導入是合理的。讓我們來看看在something.py中定義我們自己的__all__會發(fā)生什么。
# 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:
# 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
包是怎樣的呢?
當從一個包中導入全部時,__all__的做法和模塊基本一樣,不過它處理的是包中的模塊(而不是把模塊中的名都導入)。所以當我們使用from import *.時__all__說明了所有需要被導入當前命名空間的模塊。
不同之處在于,如果你在一個包的__init__.py里面沒有聲明__all__,from import *語句不會導入任何東西(這個說法也不全對,正確的說法在此)
但是,這有什么不好?
繼續(xù)讀之前,在你的Python解釋器中,執(zhí)行import this,再讀一遍Python之禪(在你孩子每晚睡前也要讀給他們)。
明確比含糊要好。
from import * 是不明確的。它沒告訴我們我們正在導入什么或者我們把什么帶入當前命名空間了。更好的做法是顯式地導入我們需要的全部名稱。這種方式下,讀者(非??赡苁俏磥淼哪阕约海┚筒粫Щ笥谀愦a中使用的一個變量/方法/類/其他東西是哪兒來的,這也告訴了我們下一點:
可讀性很重要
即使你需要導入很多東西,一個一個顯式地導入也更清楚。使用PEP 328:
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, LEFT, DISABLED, NORMAL, RIDGE, END)
你現在就能明確知道你的命名空間里有什么,使用ctrl+f能很快地告訴你它們是哪兒來的。
同時,你還總是要承擔模塊/包作者更改list內容(加/減東西)的風險。
內容擴展:
基本注意點
- 模塊:一般指一個py文件;包:含有許多py文件的文件夾,含有 或不含有(Python3中允許)__init__文件。
- 凡是在導入時帶點的,點的左邊都必須是一個包 (import a.fun1 其中a為py文件)這種導入形式是錯誤的。
- 2.from a import fun1 a為一個py文件,fun1為該文件的屬性或方法,這種導入形式是可以的。
- 一般來說 import 后面不能帶點,如:(from a import b.c是錯誤語法)
- 導入模塊時,是將模塊的py文件導入進去(執(zhí)行);導入包時,只會執(zhí)行包中的__init__文件中的代碼,故導入包時一般要導入到最底層,即from dir1.dir2.dir3 import py文件或者類、方法、屬性,只有這樣才能找到。但是你可以通過先導入一個包,然后在包的文件中的__init__中寫相關的import語句(可以絕對,也可以相對),這樣也可以通過import 包名 的方式將包中的東西導入進去。
以上就是如何理解Python中包的引入的詳細內容,更多關于Python中包的引入詳解的資料請關注腳本之家其它相關文章!
相關文章
python之tensorflow手把手實例講解斑馬線識別實現
目前智慧城市的發(fā)展,人們生活處處有科技,比如人臉識別,智慧交通,無人駕駛等前沿的科技產品也都融入了人們生活中;本篇文章帶你從頭開始實現斑馬線識別2021-09-09
使用Python將Markdown格式轉為EPUB電子書格式的代碼實現
我們每天都會接觸到大量的文本內容,無論是收藏的技術文檔、自己撰寫的筆記,還是網絡上的優(yōu)質文章,都可能面臨閱讀體驗不佳的問題,所以本文給大家介紹了使用Python將Markdown格式轉為EPUB電子書格式的實現方法,需要的朋友可以參考下2025-04-04
Python實現將sqlite數據庫導出轉成Excel(xls)表的方法
這篇文章主要介紹了Python實現將sqlite數據庫導出轉成Excel(xls)表的方法,結合實例形式分析了Python針對sqlite數據庫的連接、讀取及使用寫操作包(xlwt)生成Excel表的相關實現技巧,需要的朋友可以參考下2017-07-07

