zoukankan      html  css  js  c++  java
  • python中的包

    1.python中的包

    包将有联系的模块组织在一起,有效避免模块名称冲突问题,让应用组织结构更加清晰

    假定我们的包的例子有如下的目录结构:

    Phone/
        __init__.py
        common_util.py
        Voicedta/
            __init__.py
            Pots.py
            Isdn.py
        Fax/
            __init__.py
            G3.py
        Mobile/
            __init__.py
            Analog.py
            igital.py
        Pager/
            __init__.py
            Numeric.py
    

    Phone 是最顶层的包,Voicedta 等是它的子包。 我们可以这样导入子包:

    import Phone.Mobile.Analog
    Phone.Mobile.Analog.dial()
    

    你也可使用 from-import 实现不同需求的导入

    第一种方法是只导入顶层的子包,然后使用属性/点操作符向下引用子包树:

    from Phone import Mobile
    Mobile.Analog.dial('555-1212')
    

    此外,我们可以还引用更多的子包:

    from Phone.Mobile import Analog
    Analog.dial('555-1212')
    

    事实上,你可以一直沿子包的树状结构导入:

    from Phone.Mobile.Analog import dial
    dial('555-1212')
    

    在我们上边的目录结构中,我们可以发现很多的 __init__.py 文件。这些是初始化模块,from-import 语句导入子包时需要用到它。 如果没有用到,他们可以是空文件。

    包同样支持 from-import all 语句:

    from package.module import *
    

    然而,这样的语句会导入哪些文件取决于操作系统的文件系统。所以我们在__init__.py 中加入 __all__ 变量。该变量包含执行这样的语句时应该导入的模块的名字。它由一个模块名字符串列表组成.。

    2. __all__

    Python的moudle是很重要的一个概念,moudle里一般都会有一个__init__.py文件。有的__init__.py中是空白,有的却会有__all__参数。

    如果其他页面import 的时候如果__init__.py是空白的,可以直接import到moudle的所有函数。而如果__init__.py中定义了__all__,则import 的时候只会导入__all__部分定义的内容。

    例如,我们可以这样组织一个package:

    package1/
    
        __init__.py
    
        subPack1/
    
            __init__.py
    
            module_11.py
    
            module_12.py
    
            module_13.py
    
        subPack2/
    
            __init__.py
    
            module_21.py
    
            module_22.py
    

    __init__.py可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py中也可以设置相应的内容

    现在我们在module_11.py中定义一个函数:

    def funA():
    
        print "funcA in module_11"
    

    在顶层目录(也就是package1所在的目录,当然也参考上面的介绍,将package1放在解释器能够搜索到的地方)运行python:

    >>>from package1.subPack1.module_11 import funcA
    
    >>>funcA()
    
    funcA in module_11
    

    这样,我们就按照package的层次关系,正确调用了module_11中的函数。

    细心的同学会发现,有时在import语句中会出现通配符*,导入某个module中的所有元素,这是怎么实现的呢?

    答案就在__init__.py中。我们在subPack1的__init__.py文件中写

    __all__ = ['module_13', 'module_12']
    

    然后进入python

    >>>from package1.subPack1 import *
    
    >>>module_11.funcA()
    
    Traceback (most recent call last):
    
    File "", line 1, in
    
    ImportError: No module named module_11
    

    也就是说,以*导入时,package内的module是受__init__.py限制的。

  • 相关阅读:
    [LeetCode] 464. Can I Win 我能赢吗
    [LeetCode] 255. Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列
    [LeetCode] 244. Shortest Word Distance II 最短单词距离 II
    [LeetCode] 245. Shortest Word Distance III 最短单词距离 III
    [LeetCode] 243. Shortest Word Distance 最短单词距离
    [LeetCode] 229. Majority Element II 多数元素 II
    [LeetCode] 291. Word Pattern II 词语模式 II
    [LeetCode] 290. Word Pattern 单词模式
    C#中对 XML节点进行添加,删除,查找和删除操作
    VS2010在C#头文件中添加文件注释的方法(转)
  • 原文地址:https://www.cnblogs.com/loaderman/p/6560622.html
Copyright © 2011-2022 走看看