First Part: python module with package

Introduction module

A module is a set of aggregate functions, our program can import modules in the complex module functions. Each .py Python script file can be treated as a module. Module in the form of a disk file. When a module becomes too large, and too many driving functions, then you should consider dismantling some code out of another to build a module. Modules in the period of script code can be executed directly, it can be a bunch of similar library functions in code, which can be imported into other modules (import) call. Module may comprise a block of code that runs directly, class definition, or a combination of these function definition persons.

 

Module Category: Python standard library modules, Python third-party modules, custom application modules.

Python standard library modules: Some modules are built directly in the parser, though not some of these features built into the language, but he was able to very efficiently use, and even system-level calls, no problem. These components will be different forms depending on the configuration of the operating system, such as winreg (Windows registry access) This module will only be available for Windows systems. It should be noted that there is a special module sys, which is built into every Python parser. Refer to: https://www.cnblogs.com/ribavnu/p/4886472.html

https://blog.csdn.net/sadfishsc/article/details/10390065

Python third-party modules: Non-others parser written in python scripts, third-party modules to provide official web site of the find, download: https://pypi.org/ .

Custom application modules: to write a python script.

Module role:

  1 may be the program into one file, this program structure is more clear and easy management.

   2. file functions implemented reusable, improve development efficiency.

The import statement

In Python using the keyword import to introduce a module, for example, to import the module time, you can use import to introduce in place before the beginning of the file or use.

Syntax: Import module name

When the function call module, you must add the module name to call, because there may be a function of several modules contain the same name, this time, if only to call by the function name, the interpreter can not know in the end what function to call. In order to avoid such a situation, when you call the function, you must add the module name.

import load module is divided into four general categories:

 

  1 prepared using python .py file

 

  2 has been compiled as a shared library or DLL C or C ++ extensions

 

  3 wrap a pack module, the module is organized into a series of file folders together (Note: there is a __init__.py file folder, the folder called package)

 

  4 written in C and link to the python interpreter built-in module

 

 

Import Time 
the time.sleep ( 1) # time sleeping 
# SLEEP () # will complain

We can find from sys.module the current module has been loaded, sys.module is a dictionary containing internal mapping module and module object dictionary that determines whether you need to re-import import module.

Introducing a plurality of line modules

Import Time, Random # between the modules are separated by commas 
Print (the time.time ())
 Print (the random.randint (l, 3))

Rename the import module: Import AS ...

 Sometimes you import the module name is already used in your program, or if you do not want to use an existing name. You can replace the original name with a new name.

import time as tm
print(tm.time())

python module search path

When any one of the python program starts, will be collected into the search path module path attribute sys module ( sys.path). When the file search module python where required, first search module built, if it is not built-in module, the search path list in sys.path will search according to the order from front to back path of the properties listed in the search and just find immediately stop search for the module file. Therefore, if the standard module of the same module or PythonPATH current path exists, the standard module is overwritten. That is, if there is xml.py current directory, then in the implementation of import xml, importing a module in the current directory, rather than the standard system xml.py.

import sys
print(sys.path)

from ... import statement

The import statement is all the attributes to import module, the module requires the use of variables and access to reference, Python's from statement lets you import a specified part from the module into the current namespace. Introducing this way, the entire module is not imported into the current namespace, it will only import the content import. as also supported from ..... import mode, rename introduced to the module.

from time import time,sleep
start_time = time()
print(start_time)
sleep(2)
stop_time = time()
print(stop_time)
print(stop_time-start_time)

Importing a module all the content can be used from ... import *, but not recommended, because it may result in variable naming conflicts.

from time Import *
 Print (time ()) # can directly use all the features of the time module, add the module name without the prefix

Examples of naming conflicts

from time Import *
 # if we do not know the time module if there were time (), but below the import time module own definition of a function called time of 
DEF time ():
     return  ' time the function is invoked their own definition of ' 

# use the time function under their own definition of time Import * from 
# from time Import * 
Print (time ()) # function name that is stored in the variable name is a reference to a function object, there will be a function of the same name references cover.

Note: When the Python program imports other modules, to avoid circulation import ,, A file that is imported B, B files and import the A., otherwise there is always the problem ... not the intention.

Follicles (Package)

Using the module function and variable names to avoid conflicts. Functions and variables of the same name can exist in different modules respectively, so we own in the preparation module, regardless of the name conflict with other modules. But also pay attention, try not to conflict with the built-in function name. To avoid module name collisions, Python and the introduction of the method according to the organization directory module, called the package (Package Penalty for) .

 Package is a namespace management module Python form, a "dot module name." Such as the name of a module is AB, then he says that a packet of the sub-module B A

目录中只有包含一个叫做__init__.py的文件才会被认作是一个包,__init__.py文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码。当包当作模块被导入时,__init__.py就会被执行加载。

在导入包的时候,Python会从sys.path中的目录来寻找这个包中包含的子目录。

Notes: 自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。

类的属性:
__doc__   文档字符串
__name__   类名称  
__bases__  父类组成的元组  
__dict__    保存类方法和变量等的字典    
实例的属性:
__class__    实例所属的类  
__dict__   保存实例数据的字典    
模块的属性:  
__dict__   与模块相关的字典
__name__ 模块的名称
__file__   模块文件的绝对路径

 

导入包:

导入包与导入模块的方式是一样的。当执行导入包时,__init__.py就会被执行加载。所以包其实也是个模块,__init__.py可以是空文件,不过会影响from <包名> import * 和 import <包名> 这两种导入方式。

创建__init__.py文件:

 目录中只有包含了叫做__init__.py的文件,才能被程序认作是包,模块才能被导入成功。现在我们就在msg文件夹下创建一个__init__.py文件,并且在文件中写入__all__=[ 'module_name', 'module_name' ]。

可以在__init__.py中编写其他内容,在导入时,这些编写的内容就会被执行。

可以在__init__.py中向sys.path添加当前被调用模块路径。

__all__总结:

 编写Python代码(不建议在__init__中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py简单)。

模块中不使用__all__属性,则导入模块内的所有公有属性,方法和类 。 模块中使用__all__属性,包中使用__all__属性,则表示只导入__all__中指定的属性,定义了当我们使用 from <module> import * 导入某个模块/包的时候能导出的符号(这里代表变量,函数,类等) (当然下划线开头的变量,方法和类除外)。

需要注意的是 __all__ 只影响到了 from <package> import * 或 import <package> 这种导入方式, 对于 from <module|package> import <member> 导入方式并没有影响,仍然可以从外部导入。

reload()简介:

 无论时import还是from,默认情况下,模块在第一次被导入之后,其他的导入都不再有效。如果此时在另一个窗口中改变并保存了模块的源代码文件,也无法更新该模块。这样设计原因在于,导入是一个开销很大的操作(导入必须找到文件,将其编译成字节码,并且运行代码),以至于每个文件、每个程序运行不能够重复多于一次。当一个模块被导入到一个脚本,模块代码只会被执行一次。因此,如果你想重新执行模块里代码,可以用reload()函数,该函数会重新导入之前导入过的模块。reload()是imp模块中的一个函数,所以要使用imp.reload()之前,必须先导入imp,它的参数是一个已经成功被导入过的模块变量。也就是说该模块必须在内存中已经有自己的模块对象。reload()会重新执行模块文件,并将执行得到的属性完全覆盖到原有的模块对象中。也就是说,reload()会重新执行模块文件,但不会在内存中建立新的模块对象,所以原有模块对象中的属性可能会被修改。语法:reload(module_name)

 

import random
def mul(x,y):
    return x*y
print(random.randint(3,3))  #此时random.randint()是随机函数。
random.randint = mul  #变为乘法函数
print(random.randint(3,3))
from imp import reload
reload(random)
print(random.randint(3,3)) #变回随机函数。

 

导入模块的细节

py文件分两种:用于执行的程序文件和用于导入的模块文件。当直接使用python a.py的时候表示a.py是用于执行的程序文件,通过import/from方式导入的py文件是模块文件。

__name__属性用来区分py文件是程序文件还是模块文件:

  • 当文件是程序文件的时候,该属性被设置为__main__
  • 当文件是模块文件的时候(也就是被导入时),该属性被设置为自身模块名

对于python来说,因为隐式自动设置,该属性就有了特殊妙用:直接在模块文件中通过if __name__ == "__main__"来判断,然后写属于执行程序的代码,如果直接用python执行这个文件,说明这个文件是程序文件,于是会执行属于if代码块的代码,如果是被导入,则是模块文件,if代码块中的代码不会被执行。

导入模块的过程:

python的import是在程序运行期间执行的,并非像其它很多语言一样是在编译期间执行。也就是说,import可以出现在任何地方,只有执行到这个import行时,才会执行导入操作。且在import某个模块之前,无法访问这个模块的属性。

python在import导入模块时,首先搜索模块的路径,然后编译并执行这个模块文件。虽然概括起来只有两个过程,但实际上很复杂。

Python中所有加载到内存的模块都放在sys.modules。sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序员import一个模块文件时,首先会在这个字典查找是否已经加载了此模块,如果加载了则只是将模块的名字加入到正在调用import的模块的Local名字空间中(如果在全局作用域导入模块,则把模块名加入全局命名称空间,如果是在局部作用域导入模块,则模块名加入局部名称空间)。如果没有加载则从sys.path目录中按照模块名称查找模块文件,模块文件可以是py、pyc、pyd,找到后创建新的module对象(此时module对象的 __dict__ 属性为空),并将模块名与module对象的引用加入字典sys.modules中,然后编译、执行模块文件载入内存,并填充module对象的属性__dict__,按照一定的规则将一些结果放进这个module对象中,最后将模块名称导入到当前的Local名字空间。

注意细节:编译、执行模块文件、将结果保存到module对象中。

关于编译、执行模块文件的细说:

模块第一次被导入的时候,会进行编译,并生成.pyc字节码文件,然后python执行这个pyc文件。当模块被再次导入时,如果检查到pyc文件的存在,且和源代码文件的上一次修改时间戳mtime完全对应(也就是说,编译后模块文件的源代码没有进行过修改),则直接装载这个pyc文件并执行,不会再进行额外的编译过程。当然,如果修改过模块文件的源代码,将会重新编译得到新的pyc文件。

注意,并非所有的py文件都会生成编译得到的pyc文件,对于那些只执行一次的程序文件,会将内存中的编译结果在执行完成后直接丢弃(多数时候如此,但仍有例外,比如使用compileall模块可以强制编译成pyc文件),但模块会将内存中的编译结果持久化到pyc文件中。另外,运行字节码pyc文件并不会比直接运行py文件更快,执行它也一样是一行行地解释、执行,唯一快的地方在于导入装载的时候无需重新编译而已。

执行模块文件(已完成编译)的时候,按照一般的执行流程执行:一行一行地、以代码块为单元执行。一般地,模块文件中只用来声明变量、函数等属性,以便提供给导入它的模块使用,而不应该有其他任何操作性的行为,比如print()操作不应该出现在模块文件中,但这并非强制。

总之,执行完模块文件后,这个模块文件将有一个自己的全局名称空间,在此模块文件中定义的变量、函数等属性,都会记录在此名称空间中。

最后,模块的这些属性都会保存到模块对象中。由于这个模块对象赋值给了模块变量module_name,所以通过变量module_name可以访问到这个对象中的属性(比如变量、函数等),也就是模块文件内定义的全局属性。

参考链接https://www.cnblogs.com/qq78292959/archive/2013/05/17/3083961.html

 创建模块与包

目录结构package目录与test目录是同级的:

 

print('package/package2目录下的__init__模块被加载')
package/package2/__init__.py
print('package/package2目录下的module1.py执行加载')
print('package/package2目录下module1模块的__name__属性值为:{}'.format(__name__))
package/package2/module1.py
'''导入与父目录的父目录同级的模块'''
# import test.module1 as md
from test import module1
package/package2/test1.py
__all__ = ['module1']
print('package目录下的__init__模块被加载')
package/__init__.py
print('package目录下的module1.py执行加载')
print('package目录下的module1模块的__name__属性值为:{}'.format(__name__))
def add(x,y):
    return x+y

def mul(x,y):
    return x*y
package/module1.py
'''同目录下的模块导入方式'''
# import module1
# from package import module1
# from module2 import *  #不推荐使用,避免命名冲突
# print('package目录下的module1.py执行加载')
# print('module1模块的__name__属性值为:{}'.format(__name__))
# def add(x,y,z):
#     return x+y+z
# def mul(x,y,z):
#     return x*y*z
# print(module1.add(2,3))

'''导入与父目录同级的模块的方法'''
# import test #导入test包,实质上是导入test目录下的 __init__模块,此模块有什么属性,导入的test就有什么属性。
# print(test.module1.__name__)
# import test.module1 as md
# from test import module1

'''导入同目录下的包'''
# import package2.module1 as md
# from package2 import module1
package/test1.py
print('test目录下的__init__.py被加载')
__all__ = ['module1'] # 若允许通过包名导入所有模块,必须给__all__实现赋值
from test import * #表示导入同目录的所有模块
test/__init__.py
print('test目录下的module1被加载')
test/module1.py

 若python解释器无法找到可根据模块的所在目录给sys.path添加搜索路径:

 

 编写标准模块的模板

编写一个hello.py的模块

 1 #!/usr/bin/env python3 
 2 # -*- coding: utf-8 -*-
 3 
 4 ' a test module '
 5 
 6 __author__ = 'Michael Liao'
 7 
 8 import sys
 9 
10 def test():
11     args = sys.argv   # argv参数用列表存储命令行的所有参数
12     if len(args)==1:  # 当列表长度为1时即只有一个参数时
13         print('Hello, world!')
14     elif len(args)==2: # 当命令行有两个参数时
15         print('Hello, %s!' % args[1])
16     else:
17         print('Too many arguments!')
18 
19 if __name__=='__main__':
20     test()

第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;

第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

第6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;

第8行是导入sys模块,导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称,例如:运行python3 hello.py获得的sys.argv就是['hello.py'],注意这里python3不算是参数;运行python3 hello.py Michael获得的sys.argv就是['hello.py', 'Michael]

第19行表示当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

以上就是Python模块的标准文件模板,当然也可以全部删掉不写,但是,按标准办事肯定没错。

 

Guess you like

Origin www.cnblogs.com/us-wjz/p/10958625.html