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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python中包(package)的调用方式

發布時間:2024/4/15 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python中包(package)的调用方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python 是通過module組織代碼的,每一個module就是一個python文件,但是modules是通過package來組織的。

如果我們自己寫著玩,有的時候就是一兩個Python文件在同級目錄下,但是當我們開始嘗試開發更為復雜的項目的時候,package這個概念的使用就有助于我們組織我們寫的一個個modules。

module的概念相對簡單,所以不會再多說,主要是說一下package。

Python package

package的定義很簡單,在當面目錄下有__init__.py文件的目錄即為一個package。

但是這會分為兩種情況,第一種情況是一個空的__init__.py文件,另外一個情況是寫了代碼的__init__.py文件。不管是空的還是有內容的,這個目錄都會被認為是一個package,這是一個標識。

package的初始化工作

一個package 被導入,不管在什么時候__init__.py的代碼都只會被執行一次

>>> import package hello world >>> import package >>> import package

由于 package 被導入時 __init__.py 中的可執行代碼會被執行,所以小心在 package 中放置你的代碼,盡可能消除它們產生的副作用,比如把代碼盡可能的進行封裝成函數或類。

__init__.py內的導入順序

當我嘗試導入

from package import something

import語句會首先檢查something是不是__init__.py的變量,然后檢查是不是subpackage,再檢查是不是module,最后拋出ImportError

所以檢查順序如下:

  • __init__.py 文件內變量
  • 是不是package內的subpackage
  • 是不是package內的module
  • 看個例子

    我們有一個如下結構的package

    在a.py文件內有一個函數

    def bar():print("Hello, function 'bar' from module 'a' calling")

    在b.py文件內有一個函數

    ?

    def foo():print("Hello, function 'foo' from module 'b' calling")

    然后我們添加一個空的__init__.py 文件在simple_package里面。

    我們看下,當我們import simple_package的時候到底會發生什么事情(在simple_package內激活Python shell 或者simple_package的的路徑被包含在python的sys.path或者在PYTHONPATH的環境變量中)

    ?

    >>> import simple_package >>> >>> simple_package <module 'simple_package' from '/home/bernd/Dropbox (Bodenseo)/websites/python-course.eu/examples/simple_package/__init__.py'> >>> >>> simple_package.a Traceback (most recent call last):File "<stdin>", line 1, in <module> NameError: name 'a' is not defined >>> >>> simple_package.b Traceback (most recent call last):File "<stdin>", line 1, in <module> NameError: name 'b' is not defined

    我們可以看到simple_package已經被成功導入,但是a.py和b.py并沒有被導入

    當然了,如果你希望使用import simple_package后自動加載a或者b 模塊,這里有兩種辦法。

    第一種就是在__init__.py內導入a或者b模塊,然后保存再激活python的交互環境

    ?

    #__init__.py import a import b

    當你再次嘗試import simple_package后,就可以使用simple_package.a.bar()來使用模塊a中的bar()函數了。

    第二辦法就是手動導入,當你想使用模塊a中的bar()函數時,需要手動導入

    ?

    import simple_package.a as a

    然后就是可以a.bar()來使用bar()函數了。

    一個更復雜的例子

    這是一個來自官方的例子

    文件結構如下

    ?

    sound |-- effects | |-- echo.py | |-- __init__.py | |-- reverse.py | `-- surround.py |-- filters | |-- equalizer.py | |-- __init__.py | |-- karaoke.py | `-- vocoder.py |-- formats | |-- aiffread.py | |-- aiffwrite.py | |-- auread.py | |-- auwrite.py | |-- __init__.py | |-- wavread.py | `-- wavwrite.py `-- __init__.py

    你可以將這個package的例子下載下來。如果直接使用import sound來導入這個package,我們可以導入package sound,但是sound的子package(effects,filters,formats)并不會被自動導入。子package不會被自動導入的原因是因為在sound目錄下的__init__.py文件并沒有任何關于導入子package的代碼。

    我們來看下在sound目錄下的__init__.py的代碼

    ?

    """An empty sound packageThis is the sound package, providing hardly anything!"""print("sound package is getting imported!")

    然后我們導入sound試下

    ?

    >>> import sound sound package is getting imported! >>> sound <module 'sound' from '/home/bernd/packages/sound/__init__.py'> >>> sound.effects Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: module 'sound' has no attribute 'effects'

    如果你想使用子package的內容,但是在父package的__init__.py的文件內并沒有導入,你需要手動導入

    ?

    >>> import sound.effects effects package is getting imported! >>> sound.effects <module 'sound.effects' from '/home/bernd/packages/sound/effects/__init__.py'>

    如果你希望python幫你自動導入sound.effects你可以往sound目錄下的__init__.py文件寫入

    ?

    """An empty sound packageThis is the sound package, providing hardly anything!"""import sound.effects print("sound package is getting imported!")

    那么你下次運行的時候python就會自動幫你導入sound.effects

    ?

    >>> import sound effects package is getting imported! sound package is getting imported!

    當然了,除了使用絕對路徑你可以使用相對路徑來導入sound.effects

    ?

    """An empty sound packageThis is the sound package, providing hardly anything!"""from . import effects print("sound package is getting imported!")

    這跟linux的命令行比較像,.代表當前目錄,..代表上級目錄

    所以你可以在sound.effects的__init__.py文件內寫入

    ?

    from .. import formats

    來導入sound.formats。

    當你使用sound的時候就會發現,sound.effects和sound.formats都被導入了

    ?

    >>> import sound formats package is getting imported! effects package is getting imported! sound package is getting imported!

    最后我想給你展示下,怎么從sound.effects導入sound.filters.karaoke模塊,將一下代碼加入到sound.effects的__init__.py文件中

    ?

    """An empty effects packageThis is the effects package, providing hardly anything!"""from .. import formats from ..filters import karaoke print("effects package is getting imported!")

    激活python的交互環境以后,嘗試import sound

    ?

    >>> import sound formats package is getting imported! filters package is getting imported! Module karaoke.py has been loaded! effects package is getting imported! sound package is getting imported!

    現在我們可以使用karaoke的函數了

    ?

    >>> sound.filters.karaoke.func1() Funktion func1 has been called! >>>

    把你的整個package都導入進來

    還是用前面的例子,這一次,我會額外的加入一個叫做foobar的模塊在主目錄,你可以在這里下載例子

    我們嘗試使用*來進行全部的導入

    ?

    >>> from sound import * sound package is getting imported!

    我們可以看到僅僅是導入了sound這個package但是其他的內容并沒有導入。

    ?

    >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

    __all__

    我們可以使用__all__這個魔法變量來手動導入模塊和子package,當你定義了__all__到__init__.py文件以后,python會根據你在list內給出的元素進行逐個導入

    ?

    __all__ = ["formats", "filters", "effects", "foobar"]

    所以我們可以再次導入試試

    ?

    >>> from sound import * sound package is getting imported! formats package is getting imported! filters package is getting imported! effects package is getting imported! The module foobar is getting imported

    看下dir()

    ?

    >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'effects', 'filters', 'foobar', 'formats'] >>>

    你會發現所有模塊都已經被順利導入。

    那如果我們僅僅導入sound.effectspackage內所有內容呢,會發生什么,我們import的時候到底import的是什么。

    我們看下結果

    ?

    >>> from sound.effects import * sound package is getting imported! effects package is getting imported! >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__'] >>>

    你會發現他僅僅是導入了sound.effects這個package,跟你沒有修改sound的__init__.py之前是類似情況,僅僅是導入了這個package。

    所以你也可以修改sound.effects的__init__.py文件來導入effects內的所有模塊

    ?

    __all__ = ["echo", "surround", "reverse"]

    看下結果

    ?

    >>> from sound.effects import * sound package is getting imported! effects package is getting imported! Module echo.py has been loaded! Module surround.py has been loaded! Module reverse.py has been loaded! >>> >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'echo', 'reverse', 'surround'] >>>

    總結

  • 在 from package import * 語句中,如果 __init__.py 中定義了 __all__ 魔法變量,那么在__all__內的所有元素都會被作為模塊自動被導入(ImportError任然會出現,如果自動導入的模塊不存在的話)。
  • 如果 __init__.py 中沒有 __all__ 變量,導出將按照以下規則執行:
  • 此 package 被導入,并且執行 __init__.py 中可被執行的代碼
  • __init__.py 中定義的 variable 被導入
  • __init__.py 中被顯式導入的 module 被導入


  • 作者:brakchen
    鏈接:https://www.jianshu.com/p/178c26789011
    來源:簡書
    ?

    總結

    以上是生活随笔為你收集整理的Python中包(package)的调用方式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。