Python模块与包

Posted HT . WANG

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python模块与包相关的知识,希望对你有一定的参考价值。

1.构建一个模块的层级包

在文件系统上组织你的代码,并确保每个目录都定义了一个__init__.py文件

graphics/
    __init__.py
    primitive/
        __init__.py
        line.py
        fill.py
        text.py
    formats/
        __init__.py
        png.py
        jpg.py

以下三种导入包形式:

import graphics.primitive.line
from graphics.primitive import line
import graphics.formats.jpg as jpg

2.控制模块被全部导入的内容

当使用’from module import *’ 语句时将该模块中所有方法导出,如何从模块或包导出的符号进行精确控制

# somemodule.py
def spam():
    pass

def grok():
    pass

blah = 42
# Only export 'spam' and 'grok'
__all__ = ['spam', 'grok'] #定义一个变量 __all__ 来明确地列出能够导出的内容

3.使用相对路径名导入包中子模块

mypackage/
    __init__.py
    A/
        __init__.py
        spam.py
        grok.py
    B/
        __init__.py
        bar.py

(1)如果模块mypackage.A.spam要导入同目录下的模块grok:

# mypackage/A/spam.py

from mypackage.A import grok
from . import grok

(2)如果模块mypackage.A.spam要导入不同目录下的模块B.bar (相对路径)

# mypackage/A/spam.py

from ..B import bar

4.将模块分割成多个文件

将如下文件中两个模块进行分割到不同文件中,但不影响运行逻辑

# mymodule.py
class A:
    def spam(self):
        print('A.spam')

class B(A):
    def bar(self):
        print('B.bar')

(1)首先用mymodule目录来替换文件mymodule.py

mymodule/
    __init__.py
    a.py
    b.py

(2)在a.py文件中插入以下代码:

# a.py
class A:
    def spam(self):
        print('A.spam')

(3)在b.py文件中插入以下代码:

# b.py
from .a import A
class B(A):
    def bar(self):
        print('B.bar')

(4)在 __init__.py 中,将2个文件粘合在一起

# __init__.py
from .a import A
from .b import B

(5)产生的包MyModule将作为一个单一的逻辑模块

>>> import mymodule
>>> a = mymodule.A()
>>> a.spam()
A.spam
>>> b = mymodule.B()
>>> b.bar()
B.bar
>>>

5.利用命名空间导入目录分散的代码

希望能用共同的包前缀将所有组件连接起来,不是将每一个部分作为独立的包来安装

在不同的目录里有相同的命名空间,但是要删去用来将组件联合起来的__init__.py文件

foo-package/
    spam/
        blah.py

bar-package/
    spam/
        grok.py

在上述这2个目录里,都有着共同的命名空间spam。在任何一个目录里都没有__init__.py文件

>>> import sys
>>> sys.path.extend(['foo-package', 'bar-package'])
>>> import spam.blah
>>> import spam.grok
>>>

6.重新加载模块

对模块源码进行了修改,想重新加载已经加载的模块

用imp.reload()来重新加载先前加载的模块

# spam.py
def bar():
    print('bar')

def grok():
    print('grok')

>>> import spam
>>> from spam import grok
>>> spam.bar()
bar
>>> grok()
grok
>>>

修改后重新加载

# spam.py
def bar():
    print('bar')

def grok():
    print('New grok')

>>> import imp
>>> imp.reload(spam)

>>> spam.bar()
bar
>>> spam.grok() # Notice new output
New grok
>>>

7.运行目录或压缩文件

如果你的应用程序已经有多个文件,你可以把你的应用程序放进它自己的目录并添加一个__main__.py文件。 

myapplication/
    spam.py
    bar.py
    grok.py
    __main__.py

可以简单地在顶级目录运行Python解释器:

bash % python3 myapplication #脚本运行 解释器将执行__main__.py文件作为主程序

打包文件同样适用

bash % ls
spam.py bar.py grok.py __main__.py
bash % zip -r myapp.zip *.py
bash % python3 myapp.zip
... output from __main__.py ...

8.读取位于包中的数据文件

mypackage/
    __init__.py
    somedata.dat 数据文件
    spam.py 数据读取功能

spam.py文件需要读取somedata.dat文件中的内容

# spam.py

import pkgutil
data = pkgutil.get_data(__package__, 'somedata.dat')

9.将文件夹加入到sys.path

(1)使用PYTHONPATH环境变量来添加

bash % env PYTHONPATH=/some/dir:/other/dir python3
Python 3.3.0 (default, Oct 4 2012, 10:17:33)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/some/dir', '/other/dir', ...]
>>>

(2)创建一个.pth文件,将目录列举出来

# myapplication.pth
/some/dir
/other/dir

该文件通常位于/usr/local/lib/python3.3/site-packages 或者 ~/.local/lib/python3.3/sitepackages。当解释器启动时,.pth文件里列举出来的存在于文件系统的目录将被添加到sys.path

10. 通过字符串名导入模块

使用importlib.import_module()函数来手动导入名字为字符串给出的一个模块或者包的一部分

>>> import importlib
>>> math = importlib.import_module('math')#mport_module只是简单地执行和import相同的步骤,但是返回生成的模块对象。只需要将其存储在一个变量,然后像正常的模块一样使用
>>> math.sin(2)
0.9092974268256817
>>> mod = importlib.import_module('urllib.request')
>>> u = mod.urlopen('http://www.python.org')
>>>

11.创建新的Python环境

(1)安装第三方包

pip install --user packagename

(2)配置环境:

可以使用 pyvenv 命令创建一个新的“虚拟”环境。 这个命令被安装在Python解释器同一目录,或Windows上面的Scripts目录中

bash % pyvenv Spam
bash %

bash % cd Spam
bash % ls
bin include lib pyvenv.cfg
bash %

bash % Spam/bin/python3
Python 3.3.0 (default, Oct 6 2012, 15:45:22)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pprint import pprint
>>> import sys
>>> pprint(sys.path)
['',
'/usr/local/lib/python33.zip',
'/usr/local/lib/python3.3',
'/usr/local/lib/python3.3/plat-darwin',
'/usr/local/lib/python3.3/lib-dynload',
'/Users/beazley/Spam/lib/python3.3/site-packages']
>>>

 12.分发包

如果你想分发你的代码,第一件事就是给它一个唯一的名字,并且清理它的目录结构

projectname/
    README.txt
    Doc/
        documentation.txt
    projectname/
        __init__.py
        foo.py
        bar.py
        utils/
            __init__.py
            spam.py
            grok.py
    examples/
        helloworld.py
        ...

(1)首先要编写一个 setup.py 

# 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'],
)

(2)创建一个 MANIFEST.in 文件,列出所有在你的包中需要包含进来的非源码文件

# MANIFEST.in
include *.txt
recursive-include examples *
recursive-include Doc *

(3)setup.py 和 MANIFEST.in 文件放在包的最顶级目录projectname下

(4)执行命令来创建一个源码分发包

% bash python3 setup.py sdist

最终会根据系统平台创建一个文件比如”projectname-1.0.zip” 或 “projectname-1.0.tar.gz”,

以上是关于Python模块与包的主要内容,如果未能解决你的问题,请参考以下文章

Python模块与包

python-模块与包

Python/模块与包之模块

python之路---模块与包

Python模块与包

python—-模块与包1