• Module、__init__.py 文件解析


    一、什么是Module?

    一个python Module就是一个模块,本质就是一个.py文件,其中包含了python对象的定义和python语句。

    在模块内部,模块名存储在全局变量__name__中,可以直接在Module中用__name__变量的到模块名。

    module是为了我们能够重复使用一些对象,比如类、函数,而将这些对象定义放在一个.py文件(module)中,或是将一个较大的工程分解为多个.py文件,易于维护。

    1. 模块的定义和引入

    例如,我们现在写一个模块,名字为:fibo.py:

     1 print("__name__", __name__) //语句
     2 
     3 def fib(n): //函数定义
     4     a, b = 0, 1
     5     result = []
     6 
     7     print("in fib()", __name__)
     8 
     9     while(b<n):
    10         result.append(b)
    11         a, b = b, a+b
    12     print(result)

    如果我们在另一个文件:testModule.py中直接导入这个Module

    1 import fibo

    结果是:

    /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/lesley/PycharmProjects/test/fibo.py
    __name__ __main__
    
    Process finished with exit code 0

    也就是说:这个module的语句被执行了,但是其中所定义的函数并没有执行。如果我们想要运行其中定义的函数,则需要import 这个module中的函数,例如

    1 from fibo import fib
    2 fib(10)

    结果是:

    /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/lesley/PycharmProjects/test/testModule.py
    __name__ fibo
    in fib() fibo
    [1, 1, 2, 3, 5, 8]
    
    Process finished with exit code 0

    2. Module的加载

    每个Module中都包含对象的定义和一些语句,这些语句是用来初始化Module的,这些语句会在这个Module第一次被import的时候执行,多次import也只会执行一次,当这个Module被作为一个Script来运行时也会被执行。

    两种import方式:

    • import module_name1[as name1], module_name2[as name2]
    • from module_name import item1[as name1], item2[as name2]

    3.Module搜索路径

    当在testModule.py运行时,遇到需要import这个名为fibo的Module时,Python Interpreter 首先会在built-in Module中找有没有叫这个名字的,如果没有,则会从一系列的目录去寻找这个Module,这些目录都存在sys.path中。

    built-in Module是Python的标准库,主要提供了了很重要的但是Python没有提供的功能(例如:sys module)

    sys.path:是python的搜索模块的路径集,是一个list ,它的初始值是

    1. 当前目录,也就是当前执行脚本的目录
    2. 环境变量PYTHONPATH中存储的值
    3. Python包的安装目录,例如:/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages

    可以在命令行中查看:

    可以在python 环境下使用sys.path.append(path)添加相关的路径,但在退出python环境后自己添加的路径就会自动消失

    例如,我们要添加fibo.py所在的路径:/Users/lesley/Downloads 进sys.path,则可以修改代码:“

    import sys
    sys.append("/Users/lesley/Downloads/")

    因为这个这时暂时的,所以更永久的方式是将fibo.py复制到python包的安装目录:/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages

    4. 把module作为Script来执行(if __name__ == "__main__")

    Mudule可以直接执行也可以被调用,当自己直接执行时,解释器会把__name__设置为__main__,而被调用执行时,也就是作为参数传递给Interpret时,__name__的值为自己的模块名,所以我们可以在一个模块代码的最后写一个 if __name__ == "__main__",以用来测试、调试这个Module,而当外界需要调用这个模块的时候,就不会执行其中的代码

     1 print ("__name__ :", __name__)
     2 def fib(n):
     3         a, b = 0, 1
     4         result = []
     5         print ("in fib() :", __name__)
     6         while (b<n):
     7                 result.append(b)
     8                 a, b = b, a+b
     9         print(result)
    10 
    11 if __name__ == "__main__":
    12         import sys
    13         fib(int(10))

    执行的结果:

     

     

    5. dir()——built-in函数的目录

    6. 模块包(package)

    Package可以理解为组织起来的Module的一个层次结构,也就是一个目录。它包含了sub-package或者是Module。

    要让解释器将一个目录看作是一个Package,也就是加入到sys.path下面,则该目录下必须要有一个__init__.py文件。

    这个__init__.py文件可以为空,也可以用来做初始化工作,以及设置__all__变量。

     

    二. 测试项目中的结构更新

    当我们写完了测试用例test_CustomerLogin,并将其放在testcase目录下的时候,如果直接在run_test引入该测试用例(import test_CustomerLogin),运行时会报错: 提示找不到该文件。这时我们需要做两件事情:

    1. 在testcase目录下创建一个__init__.py文件,文件内容可以为空

    2. 在run_test.py中添加两行代码:

    1 import sys
    2 sys.path.append("	estcase")

    即:将 estcase目录添加到sys.path下


    三. __init__.py文件解析

    首先,我们先了解,python在执行import语句时,执行的操作

    第 1 步:创建一个新的、空的module(模块、组件)对象(它可能包含多个module)

    第 2 步:把这个新建的module插入到sys.module中

    第 3 步:装载module对象(如果需要,首先必须编译)

    • 首先找到module程序所在的位置,
      • 搜索顺序:当前路径(以及从当前目录指定的sys.path)——PYTHONPATH——python的安装设置相关的默认路径
      • 所以,如果当前路径或PYTHONPATH中存在与标准module同样的module,则会覆盖标准module。例如,如果当前目录下存在xml.py,在在执行import xml时,导入的是当前目录下的Module,而不是系统标准的xml

    第 4 步:执行新的mudule中对应的代码

    我们将testcase目录添加到系统path下,run_test就可以正常调用其目录下所有的测试用例。

    而__init__.py就是标志该目录是可以用的包。该文件中可以有内容,当我们在导入这个python包的时候,实际上就是导入了它的__init__文件

  • 相关阅读:
    Qt之JSON生成与解析
    Qt的QLineEdit显示密码
    Ubuntu14.04 64位运行32位程序
    Xcode 7在支持ipad的设备中需要支持分屏!
    「模板」平衡树
    [NOI2016]区间 题解(决策单调性+线段树优化)
    [NOIP模拟测试12]题解
    [笔记乱写]0/1分数规划
    [NOIP模拟测试11] 题解
    [SCOI2014]方伯伯的玉米田 题解(树状数组优化dp)
  • 原文地址:https://www.cnblogs.com/lesleysbw/p/5911838.html
Copyright © 2020-2023  润新知