1. 程式人生 > >沉澱再出發:在python3中匯入自定義的包

沉澱再出發:在python3中匯入自定義的包

沉澱再出發:在python3中匯入自定義的包

一、前言

    在python中如果要使用自己的定義的包,還是有一些需要注意的事項的,這裡簡單記錄一下。

二、在python3中匯入自定義的包

 2.1、什麼是模組、包、庫?

  模組:就是.py檔案,裡面定義了一些函式和變數,需要的時候就可以匯入這些模組。
  包:在模組之上的概念,為了方便管理而將檔案進行打包。包目錄下第一個檔案便是 __init__.py,然後是一些模組檔案和子目錄,假如子目錄中也有 __init__.py,那麼它就是這個包的子包了。
  庫:具有相關功能模組的集合。這也是Python的一大特色之一,即具有強大的標準庫、第三方庫以及自定義模組。標準庫就是下載安裝的python裡那些自帶的模組,要注意的是,裡面有一些模組是看不到的比如像sys模組,這與linux下的cd命令看不到是一樣的情況。第三方庫是由其他的第三方機構,釋出的具有特定功能的模組。自定義模組是使用者自己編寫的模組。
  這三個概念實際上都是模組,只不過是個體和集合的區別。

 2.2、簡單的自定義包

  我們在任何一個目錄下面新建一個資料夾和兩個.py檔案,然後在資料夾下面建立一個空的__init__.py檔案和.py的檔案,然後開始實驗。

 首先我們看看在同級目錄下各個模組的引用情況

  

  開啟CMD,將目錄切換到當前資料夾下,執行程式,可以發現在同目錄下正常執行並且生成了快取檔案:

 然後我們測試在不同目錄下

 

  在sub1資料夾下我們因為建立了__init__.py檔案,系統會認為這個檔案是一個package,因此,就會嘗試著載入和發現我們定義的模組:

   然後再use.py中,我們發現可以正常的使用和執行了:

   其實如果我們將__init__.py檔案刪除了,結果也會是一樣的,同樣可以執行:

    但是如果我們使用import 包名.模組名的時候就會出現問題了,我們會發現如果是在同級上可以正常使用,但是在不同的包下面,除非我們使用全稱,要不然的話是不能成功的(注意:這個時候我們的包依舊沒有使用__init__.py檔案):

   即使我們使用了__init__.py依舊會是這樣:

 那麼到底是為什麼呢?

    這是因為python3需要絕對路徑引用,從project的根位置開始指明被引模組的位置。通用格式為:from directory import module 。如果module存在於directory1下的directory2,那麼建議寫成from directory1.directory2 import module,其中程式執行時根目錄(mount)為directory1。使用from語句可以把模組直接匯入當前名稱空間,from語句並不引用匯入物件的名稱空間,而是將被匯入物件直接引入當前名稱空間。但是如果直接使用import的時候,就會使用另一個名稱空間下面的函式或者變數,這個時候我們就需要使用全稱來指代

   那麼有沒有解決辦法呢,當然是有的,比如我們將子包加入到sys.path中,這樣系統就能自動識別了(這個時候不需要__init__.py檔案):

1 import sys
2 sys.path.append('sub1')
3 import mytest
4 print(mytest.sub(2,3))

 2.3、__init__.py的作用

  大家可能注意到,我一直在提這個檔案,那麼我們可以看到在很多的大型專案之中都是有這個檔案存在的,我們可以看看我們自己使用pip install XXX,從網上下載的包檔案:

   隨便找一個都會發現這個檔案的,並且在子目錄下面也都會有這個檔案的,我們看看上面的這個檔案的內容,可以發現其中將自己目錄下面的檔案進行了一種整合方便使用者直接來使用,再看看下面的子目錄中的__init__.py檔案有的為空,有的就是整合該目錄下面的檔案資源的:

  1 # pylint: disable-msg=W0614,W0401,W0611,W0622
  2 
  3 # flake8: noqa
  4 
  5 __docformat__ = 'restructuredtext'
  6 
  7 # Let users know if they're missing any of our hard dependencies
  8 hard_dependencies = ("numpy", "pytz", "dateutil")
  9 missing_dependencies = []
 10 
 11 for dependency in hard_dependencies:
 12     try:
 13         __import__(dependency)
 14     except ImportError as e:
 15         missing_dependencies.append(dependency)
 16 
 17 if missing_dependencies:
 18     raise ImportError(
 19         "Missing required dependencies {0}".format(missing_dependencies))
 20 del hard_dependencies, dependency, missing_dependencies
 21 
 22 # numpy compat
 23 from pandas.compat.numpy import *
 24 
 25 try:
 26     from pandas._libs import (hashtable as _hashtable,
 27                              lib as _lib,
 28                              tslib as _tslib)
 29 except ImportError as e:  # pragma: no cover
 30     # hack but overkill to use re
 31     module = str(e).replace('cannot import name ', '')
 32     raise ImportError("C extension: {0} not built. If you want to import "
 33                       "pandas from the source directory, you may need to run "
 34                       "'python setup.py build_ext --inplace --force' to build "
 35                       "the C extensions first.".format(module))
 36 
 37 from datetime import datetime
 38 
 39 # let init-time option registration happen
 40 import pandas.core.config_init
 41 
 42 from pandas.core.api import *
 43 from pandas.core.sparse.api import *
 44 from pandas.tseries.api import *
 45 from pandas.core.computation.api import *
 46 from pandas.core.reshape.api import *
 47 
 48 # deprecate tools.plotting, plot_params and scatter_matrix on the top namespace
 49 import pandas.tools.plotting
 50 plot_params = pandas.plotting._style._Options(deprecated=True)
 51 # do not import deprecate to top namespace
 52 scatter_matrix = pandas.util._decorators.deprecate(
 53     'pandas.scatter_matrix', pandas.plotting.scatter_matrix, '0.20.0',
 54     'pandas.plotting.scatter_matrix')
 55 
 56 from pandas.util._print_versions import show_versions
 57 from pandas.io.api import *
 58 from pandas.util._tester import test
 59 import pandas.testing
 60 
 61 # extension module deprecations
 62 from pandas.util._depr_module import _DeprecatedModule
 63 
 64 json = _DeprecatedModule(deprmod='pandas.json',
 65                          moved={'dumps': 'pandas.io.json.dumps',
 66                                 'loads': 'pandas.io.json.loads'})
 67 parser = _DeprecatedModule(deprmod='pandas.parser',
 68                            removals=['na_values'],
 69                            moved={'CParserError': 'pandas.errors.ParserError'})
 70 lib = _DeprecatedModule(deprmod='pandas.lib', deprmodto=False,
 71                         moved={'Timestamp': 'pandas.Timestamp',
 72                                'Timedelta': 'pandas.Timedelta',
 73                                'NaT': 'pandas.NaT',
 74                                'infer_dtype': 'pandas.api.types.infer_dtype'})
 75 tslib = _DeprecatedModule(deprmod='pandas.tslib',
 76                           moved={'Timestamp': 'pandas.Timestamp',
 77                                  'Timedelta': 'pandas.Timedelta',
 78                                  'NaT': 'pandas.NaT',
 79                                  'NaTType': 'type(pandas.NaT)',
 80                                  'OutOfBoundsDatetime': 'pandas.errors.OutOfBoundsDatetime'})
 81 
 82 # use the closest tagged version if possible
 83 from ._version import get_versions
 84 v = get_versions()
 85 __version__ = v.get('closest-tag', v['version'])
 86 del get_versions, v
 87 
 88 # module level doc-string
 89 __doc__ = """
 90 pandas - a powerful data analysis and manipulation library for Python
 91 =====================================================================
 92 
 93 **pandas** is a Python package providing fast, flexible, and expressive data
 94 structures designed to make working with "relational" or "labeled" data both
 95 easy and intuitive. It aims to be the fundamental high-level building block for
 96 doing practical, **real world** data analysis in Python. Additionally, it has
 97 the broader goal of becoming **the most powerful and flexible open source data
 98 analysis / manipulation tool available in any language**. It is already well on
 99 its way toward this goal.
100 
101 Main Features
102 -------------
103 Here are just a few of the things that pandas does well:
104 
105   - Easy handling of missing data in floating point as well as non-floating
106     point data.
107   - Size mutability: columns can be inserted and deleted from DataFrame and
108     higher dimensional objects
109   - Automatic and explicit data alignment: objects can be explicitly aligned
110     to a set of labels, or the user can simply ignore the labels and let
111     `Series`, `DataFrame`, etc. automatically align the data for you in
112     computations.
113   - Powerful, flexible group by functionality to perform split-apply-combine
114     operations on data sets, for both aggregating and transforming data.
115   - Make it easy to convert ragged, differently-indexed data in other Python
116     and NumPy data structures into DataFrame objects.
117   - Intelligent label-based slicing, fancy indexing, and subsetting of large
118     data sets.
119   - Intuitive merging and joining data sets.
120   - Flexible reshaping and pivoting of data sets.
121   - Hierarchical labeling of axes (possible to have multiple labels per tick).
122   - Robust IO tools for loading data from flat files (CSV and delimited),
123     Excel files, databases, and saving/loading data from the ultrafast HDF5
124     format.
125   - Time series-specific functionality: date range generation and frequency
126     conversion, moving window statistics, moving window linear regressions,
127     date shifting and lagging, etc.
128 """

 下面我們看看__init__.py的作用:

     __init__.py檔案用於組織包(package)。當資料夾下有__init__.py時,表示當前資料夾是一個package,其下的多個module統一構成一個整體。這些module都可以通過同一個package引入程式碼中。__init__.py檔案可以什麼都不寫,但如果想使用from package1 import *這種寫法的話,需要在__init__.py中加上:

1 __all__ = ['file1','file2'] #package1下有file1.py,file2.py

 我們看一個例子:

 

 

    目前我們沒有__init__.py檔案,是可以執行的:

    但是我們不能使用from  sub2  import * 來使用。

    如果使用__init__.py,在其中加入下面的語句,程式就可以正常運行了,特別是當該資料夾下的模組特別多的時候就非常有用了。

1 __all__= ['file1','file2']

三、總結

     關於自定義package的匯入,我們需要理解的還有很多,只有徹底的理解了其中的道理,我們才能真正的學會去使用它。