在每個文件夾下創建__init__.py文件,這個文件將在此包下具體的模塊導入之前執行。它裡面可以定義與模塊相關的一些內容。比如發布:下面代碼只導入spam 和 grok。如果采用from module import *則會導入所有不以下劃線開頭的模塊。但若定義了__all__則只有被列舉出的模塊才會被導入,如果定義了一個空列表,則不會導入任何模塊。
def spam():
pass
def grok():
pass
age = 30
# Only export 'spam' and 'grok'
__all__ = [ 'spam', 'grok']
重新加載,這種方式不建議在生產環境中使用。
import importlib
from chapter10 import module_split
importlib. reload( module_split)
通過字符串導入模塊
req = importlib. import_module( 'requests')
res = req. get( 'http://www.python.org')
import importlib
import sys
from collections import defaultdict
_post_import_hooks = defaultdict( list)
class PostImportFinder:
def __init__( self):
self. _skip = set()
def find_module( self, full_name, path = None):
if full_name in self. _skip:
return None
self. _skip. add( full_name)
return PostImportLoader( self)
class PostImportLoader:
def __init__( self, finder):
self. _finder = finder
def load_module( self, full_name):
importlib. import_module( full_name)
module = sys. modules[ full_name]
for func in _post_import_hooks[ full_name]:
func( module)
self. _finder. _skip. remove( full_name)
return module
def imported_action( full_name):
def decorate( func):
if full_name in sys. modules:
func( sys. modules[ full_name])
else:
_post_import_hooks[ full_name]. append( func)
return func
return decorate
sys. meta_path. insert( 0, PostImportFinder())
@ imported_action( 'threading')
def warn_threads( mod):
print( 'Call Threads.')
在已存在的函數定義上添加裝飾器,imported_action裝飾器的作用是將導入時被激活的處理器函數進行注冊。該裝飾器用於檢查sys.modules,以便查看模塊是否已經被加載。如果是,處理器立即被調用,添加到_post_improts_hooks字典的一個列表中。一個模塊可以注冊多個處理器,_post_import_hooks的作用是收集所有的處理器對象。
from functools import wraps
from chapter10. modify_module import imported_action
def logged( func):
@ wraps( func)
def wrapper( * args, * * kwargs):
print( f'Calling { func. __name__} ,args: { args} ,kwargs: { kwargs} ')
return func( * args, * * kwargs)
return wrapper
@ imported_action( 'math')
def add_logging( mod):
mod. cos = logged( mod. cos)
mod. sin = logged( mod. sin)
import math
print( f'math.sin(2) = { math. sin( 2)} ')
import pkgutil
data = pkgutil. get_data( __package__, 'test_data.dat') #第一個函數可以直接使用包名。
這個功能類似動態添加庫到path路徑下。site-package目錄是第三方包和模塊安裝的目錄。如果手動安裝代碼,代碼將被安裝到site-package目錄下。配置path的pth文件必須放置在site-packages裡,但配置的路徑可以是系統上任何希望的目錄中。
import sys
print( f'sys path: { sys. path} ')
import sys
sys. path. insert( 0, '/test/dir')
sys. path. insert( 0, '/test/dir')
import sys
from os import path
file_path = path. abspath( path. dirname( __file__))
sys. path. insert( 0, path. join( file_path, 'test'))
print( f'sys path: { sys. path} ')
這個功能類似java裡的maven私服功能。上傳模塊供其它應用來dependency。
#step1:編寫setup.py文件
from distutils. core import setup
setup( name = 'projectname',
version = '1.0',
author = 'Your Name',
author_email = '[email protected]',
url = 'http://www.you.com/projectname',
packages =[ 'projectname', 'projectname.utils'],
)
#setp2:創建 MANIFEST.INF文件
include *. txt
recursive - include examples *
recursive - include Doc *
#setp3:執行命令發布
python3 setup. py sdist