当前位置 : 主页 > 编程语言 > python >

Python从门到精通(二):包装-07-模块与包

来源:互联网 收集:自由互联 发布时间:2022-06-24
一、模块 1.1、__init__.py 在每个文件夹下创建__init__.py文件,这个文件将在此包下具体的模块导入之前执行。它里面可以定义与模块相关的一些内容。比如发布:下面代码只导入spam 和

一、模块

1.1、__init__.py

在每个文件夹下创建__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')

1.2、钩子函数

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)}')

二、包

2.1、常见使用

2.1.1、读取包中的数据文件

import pkgutil
data = pkgutil.get_data(__package__, 'test_data.dat') #第一个函数可以直接使用包名。

2.1.2、将文件夹加入到sys.path

这个功能类似动态添加库到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}')

2.2、包分发

这个功能类似java里的maven私服功能。上传模块供其它应用来dependency。

#step1:编写setup.py文件

from distutils.core import setup

setup(name='projectname',
version='1.0',
author='Your Name',
author_email='you@youraddress.com',
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


上一篇:Python开发工具PyCharm使用教程:自定义 IDE
下一篇:没有了
网友评论