Iron music learning python_day29_ module and package learning 4

Most of the content is taken from the teacher's blog http://www.cnblogs.com/Eva-J/

Compile the python file

The purpose of compiling python files is to improve the speed of loading modules. It is emphasized that the speed of loading is improved, not the speed of running.

python解释器会在__pycache__目录下缓存每个模块编译后的版本,格式为:module.version.pyc。
通常会包含python的版本号。
例如,在CPython3.3版本下,my_module.py模块会被缓存成__pycache__/my_module.cpython-33.pyc。
这种命名规范保证了编译后的结果多版本共存。

Python checks the modification time of the source file against the compiled version, and needs to recompile if it is out of date.
This is a completely automatic process. And the compiled modules are platform independent,
so the same library can be shared between systems with different architectures, that is, pyc is a cross-platform bytecode, similar to JAVA and .NET, which
is executed by the python virtual machine Yes, but the content of pyc is related to the version of python, the pyc files compiled by different versions are different,
the pyc files compiled with 2.5 cannot be executed on 3.5, and the pyc files can be decompiled, so its appearance is only used for Improve the loading speed of modules.

The python interpreter does not detect caching in the following two cases.

1 If the module is directly imported on the command line, in this way, each import will be recompiled,
and the compiled result will not be stored (this should be the case for versions before python3.3)
python -m my_module.py

2 If the source file does not exist, the cached result will not be used.
If you want to use the compiled result without the source file, the compiled result must be in the source directory.

Tips:
1. Module names are case-sensitive, foo.py and FOO.py represent two modules;
2. You can use -O or -OO to convert python commands to reduce the size of compiled modules.

-O conversion will help you to remove assert statements
-OO conversion will help you to remove assert statements and __doc__ docstrings
Since some programs may depend on assert statements or docstrings, you should use these options when you are sure you need them .

3. In terms of speed, reading instructions from .pyc files to execute will not be faster than reading instructions from .py files.
Only when modules are loaded, .pyc files are faster.

4. Only use the import statement to automatically compile the file into a .pyc file.
Specifying the run script on the command line or standard input will not generate such files,
so we can use the compieall module to create all modules in a directory. pyc file.

Modules can be compiled from Python sources as a script (using python -m compileall )

python -m compileall /module_directory recursive compilation
if using python -O -m compileall /module_directory -l only one layer

When using the compile() function on the command line, python -O -m compileall is automatically used
for details: https://docs.python.org/3/library/compileall.html#module-compileall

Added: dir() function

The built-in function dir is used to find names defined in modules and returns an ordered list of strings:
import my_module
dir(my_module)

With no arguments, dir() lists the currently defined names.

dir() does not list the names of built-in functions or variables, they are all defined in the standard module builtin, you can list them,
import builtins
dir(builtins)

Bag

Packages are a way of organizing the python module namespace by using '.modulename'.

1. 无论是import形式还是from...import形式,
凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法。

2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)。

3. import导入文件时,产生名称空间中的名字来源于文件,import 包,
产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件。

强调:
1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,
而在python2中,包下一定要有该文件,否则import 包报错。

2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块。

包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间。

以下是创建(包)目录的代码(脚本),以后可以在这个基础上扩展出规范的创建脚本,自动省时:
import os
os.makedirs('glance/api')
os.makedirs('glance/cmd')
os.makedirs('glance/db')
l = []
l.append(open('glance/__init__.py','w'))
l.append(open('glance/api/__init__.py','w'))
l.append(open('glance/api/policy.py','w'))
l.append(open('glance/api/versions.py','w'))
l.append(open('glance/cmd/__init__.py','w'))
l.append(open('glance/cmd/manage.py','w'))
l.append(open('glance/db/models.py','w'))
map(lambda f:f.close() ,l)

目录结构:
glance/                   #Top-level package
├── __init__.py      #Initialize the glance package
├── api                  #Subpackage for api
│   ├── __init__.py
│   ├── policy.py
│   └── versions.py
├── cmd                #Subpackage for cmd
│   ├── __init__.py
│   └── manage.py
└── db                  #Subpackage for db
    ├── __init__.py
    └── models.py

文件内容

#policy.py
def get():
    print('from policy.py')

#versions.py
def create_resource(conf):
    print('from version.py: ',conf)

#manage.py
def main():
    print('from manage.py')

#models.py
def register_models(engine):
    print('from models.py: ',engine)

Precautions

1. The import statement related to the package is also divided into import and from...import...,
but no matter which one, no matter where it is,
you must follow a principle when importing: Anything with dots when importing , the left side of the point must be a packet, otherwise it is illegal.
Can have a series of points, such as item.subitem.subsubitem, but must follow this principle.

2. After importing, there is no such restriction in use. The left side of the dot can be packages, modules, functions, and classes (they can all call their own properties in the way of dots).
3. Compare the application scenarios of import item and from item import name:
if we want to use name directly, we must use the latter.

import

We test in a file at the same level as package glance:

import glance.db.models
glance.db.models.register_models('mysql')

from ... import ...

It should be noted that the module imported after import
must be a clear one without dots, otherwise there will be syntax errors, such as: from a import bc is wrong syntax


We test from glance.db import models
models.register_models('mysql') in a file at the same level as package glance

from glance.db.models import register_models
register_models('mysql')

__init__.py文件
不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,
都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),
这个文件可以为空,但是也可以存放一些初始化包的代码。

from glance.api import *
在讲模块时,我们已经讨论过了从一个模块内导入所有*,此处我们研究从一个包导入所有*
此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,
我们可以在这个文件中定义__all___:

在__init__.py中定义
x=10

def func():
    print('from api.__init.py')

__all__=['x','func','policy']

此时我们在于glance同级的文件中执行from glance.api import *就导入__all__中的内容(versions仍然不能导入)。

from glance.api import *
glance/

├── __init__.py      
├── api                  
│   ├── __init__.py   __all__ = ['policy','versions'] 
│   ├── policy.py
│   └── versions.py
├── cmd               __all__ = ['manage']    
│   ├── __init__.py
│   └── manage.py    
└── db                __all__ = ['models']              
    ├── __init__.py
    └── models.py

from glance.api import *
policy.get()

Absolute and relative imports

Our top-level package, glance, is written for others to use, and then there will be a need to import each other within the glance package. At
this time, there are two ways of absolute import and relative import:
absolute import: start with glance
Relative import: start with . or .. (can only be used in one package, not in different directories)

例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

在glance/api/version.py

#绝对导入
from glance.cmd import manage
manage.main()

#相对导入
from ..cmd import manage
manage.main()

测试结果:注意一定要在于glance同级的文件中测试
from glance.api import versions 

Note: When using pycharm, in some cases, it will do more for you. This is software-related and will affect your understanding of module import.
Therefore, when testing, you must go back to the command line to execute and simulate our In the production environment, you can't go online with pycharm! ! !

Of particular note are:

You can use import to import built-in or third-party modules (already in sys.path), but to absolutely avoid using import to import submodules of custom packages (not in sys.path), use from... import .. The absolute or relative import of ., and the relative import of the package can only be used in the form of from.

Import packages individually

When importing the package name alone, it will not import all the submodules contained in the package. The
solution is to use a relative path in the submodule to import the upper-level (..upper-level directory) module or the same-level (.current directory) module.
Do not ask : Can't __all__ be resolved, __all__ is used to control from...import *

Attachment: Reference Catalogue for Software Specification Development

end
2018-4-27

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325097199&siteId=291194637