Introducing day20 modules, software packages and directories specifications

1. Import module

1.1 There are two uses a python file

  1. As the program is running
  2. Module was introduced as a

1.2 What is the difference between the two that?

To file foo as an example:

1, when the foo.py is run, the value name__ __ '__main__'
2, when foo.py is introduced as a module, __ name__ value 'foo'

print('模块foo==>')

# __all__=['x',] # 控制*代表的名字有哪些
x=1
def get():
    print(x)

def change():
    global x
    x=0

def say():
    print('我还活在内存中呢。。。。')
if __name__ == '__main__':
    print('文件被执行')
    get()
    change()
else:
    # 被当做模块导入时做的事情
    print('文件被导入')
    pass

For import module is introduced

The advantages and disadvantages 1.3 import import mode

impot import modules must be added in the use of the prefix "module."
advantage : certainly not conflict with the name of the name space in the current
drawback : prefix appears in trouble

1.4 from ... impot ... statement

The import process three

  1. Producing a module namespace
  2. The name of the operation foo.py generated during operation are thrown to the name space module
  3. In the current namespace to get a name, a name and a memory address of the module name space
from foo import x # x=模块foo中值的内存地址
from foo import get
from foo import change

print(x)
print(get)
print(change)
x=333333333
print(x)
get()
change()
get()

print(x)
from foo import x # x=新地址
print(x)

For from the imported modules for

1.5 from ... impot ... pros and cons

from ... impot ... importing modules when used without prefixing

Advantage : the code more streamlined

Disadvantages : easy to be confused with the current namespace

from foo import x # x=模块foo中值1的内存地址
x=1111

Notes from ... import

  • Line of the import multiple names (not recommended)
  • The names of all-time import module can be used: *
  • Alias ​​module can be introduced from
from foo import x,get,change
from foo import get as g
name='egon'
from foo import *
print(name)

from socket import *
'''
了解知识: * 导入时是访问对应模块的__all__的值,是一个列表
__all__=['x',] # 控制*代表的名字有哪些
'''

1.6 module search path priority

Whether or import from ... import When you import the module are related to the find the problem

Priority :
a memory (built-in module)
2, a hard disk: in the order of the file are sequentially stored in sys.path lookup module to import

# 值为一个列表,存放了一系列的对文件夹
# 其中第一个文件夹是当前执行文件所在的文件夹
>>> import sys
>>> sys.path
['', 'E:\\Python\\Python38\\python38.zip', 'E:\\Python\\Python38\\DLLs', 'E:\\Python\\Python38\\lib', 'E:\\Python\\Python38', 'E:\\Python\\Python38\\lib\\site-packages']
>>

sys.path The first path is usually empty path, on behalf of the executable file is located, so when imported modules and execute files in the same directory must be working properly imported, but for the module and execute files are imported in the case where different paths, in order to ensure the module corresponding to the source file can still be found, it is necessary to add the source file path to sys.path foo.py located, the path is assumed where foo.py / pythoner / projects /

import sys
sys.path.append(r'/pythoner/projects/') #临时添加
#找foo.py就把foo.py的文件夹添加到环境变量中,获取文件的绝对路径,再添加
import foo #无论foo.py在何处,我们都可以导入它了

Learn: sys.modules view has been loaded into memory modules

import sys
import foo # foo=模块的内存地址
del foo

def func():
    import foo # foo=模块的内存地址

func()

# print('foo' in sys.modules)
print(sys.modules)

1.7 write a specification module

#!/usr/bin/env python #通常只在类lunix环境有效,作用是可以使用脚本名来执行,而无需直接调用解释器。

"The module is used to..." #模块的文档描述

import sys #导入模块

x=1 #定义全局变量,如果非必须,则最好使用局部变量,这样可以提高代码的易维护性,并且可以节省内存提高性能

class Foo: #定义类,并写好类的注释
    'Class Foo is used to...'
    pass

def test(): #定义函数,并写好函数的注释
    'Function test is used to…'
    pass

if __name__ == '__main__': #主程序
    test() #在被当做脚本执行时,执行此处的代码

1.8 supplementary function of knowledge

Type Prompt Type hinting (lowest Python 3.5)

#Python是一种强类型的动态语言
#可以:+类型,规定传入值的类型,本质上:后是添加的提示信息,可以根据需要填写
#->int 规定返回值的类型
#虽然规定了传入类型,但实际上还是可以传入其他类型的,传入值的规范
def register(name:str,age:int,hobbbies:tuple)->int:
 print(name)
 print(age)
 print(hobbbies)
 return 111

register(1,'aaa',[1,])
#可以添加默认值,默认值在类型后面添加
def register(name:str='egon',age:int=18,hobbbies:tuple=(1,2))->int:
 print(name)
 print(age)
 print(hobbbies)
 return 111
register()
res=register('egon',18,('play','music'))

1585325998024

2 bags

2.1 What is the package

Package is a folder that contains the file __init__.py

Why have 2.2 package

The nature of the package is a form of a module block, the packet is to be introduced as a module

2.3 how to use package

import mmm
print(mmm.x)
print(mmm.y)
mmm.say()

from mmm import x

The step of introducing three packets

1, resulting in a namespace
2 _ the package is run under the init _.py file, the name generated during operation are thrown into the namespace 1
3, mmm get a name in the namespace currently executing file, mmm 1 to namespaces

He stressed :
1. Import-related statements about the package is also divided into import and from ... import ... two kinds when you import must follow a principle:

Any little at the time of import, the left point must be a package, otherwise illegal.
2, packets A and B at the packet of the same name does not conflict module, such as Aa and Ba from two namespaces
3, when the import file import, generate namespace name from file, import packets generated namespace the name comes from the same file, that package _ under the init _.py, import the package is in the nature of the import file

Absolute and relative introduced introducing 2.4

# 绝对导入,以包的文件夹作为起始来进行导入
#pool下的__init__.py
from pool import versions


# 相对导入:仅限于包内使用,不能跨出包(包内模块之间的的导入,推荐使用相对导入)
# .:表示当前文件夹
# ..:表示上一层文件夹
# 局限性:.不能超出foo之外

#pool下的__init__.py
from . import versions
'''
强调:
1、相对导入不能跨出包,所以相对导入仅限于包内模块之间相互导入
2、绝对导入是没有任何限制的,所以绝对导入是一种通用的导入方式
'''

#针对包内部模块之间的相互导入推荐使用相对导入,需要特别强调:
'''
1、相对导入只能在包内部使用,用相对导入不同目录下的模块是非法的

2、无论是import还是from-import,但凡是在导入时带点的,点的左边必须是包,否则语法错误
'''

from 包 import *

'''
在使用包时同样支持from pool.futures import * ,
毫无疑问*代表的是futures下__init__.py中所有的名字,通用是用变量__all__来控制*代表的意思
'''
#futures下的__init__.py
__all__=['process','thread']

'''
包内部的目录结构通常是包的开发者为了方便自己管理和维护代码而创建的,
这种目录结构对包的使用者往往是无用的,此时通过操作__init__.py可以“隐藏”包内部的目录结构,
降低使用难度,比如想要让使用者直接使用
'''
import pool

pool.check()
pool.ProcessPoolExecutor(3)
pool.ThreadPoolExecutor(3)

# 需要操作pool下的__init__.py
from .versions import check
from .futures.process import ProcessPoolExecutor
from .futures.thread import ThreadPoolExecutor

3. Software development directory specification

In order to improve the readability and maintainability of the program, we should be well-designed software directory structure, coding style as important as this and norms. Directory specification is no hard and fast standard software, as long as you can clearly readable, assuming your software named foo, recommended directory structure is as follows

3.1 software directory structure

Foo/ 
|-- core/ # 存放业务逻辑相关代码
|   |-- core.py
|
|-- api/ # 存放接口文件,接口主要用于为业务逻辑提供数据操作。
|   |-- api.py 
|
|-- db/ # 放操作数据库相关文件,主要用于与数据库交互
|   |-- db_handle.py
|
|-- lib/ # 存放程序中常用的自定义模块
|   |-- common.py
|
|-- conf/ # 存放配置文件
|   |-- settings.py
|
|-- run.py # 程序的启动文件,一般放在项目的根目录下,因为在运行时会默认将运行文件所在的文件夹				sys.path的第一个路径,这样就省去了处理环境变量的步骤
|-- setup.py # 安装、部署、打包的脚本。
|-- requirements.txt # 存放软件依赖的外部Python包列表
|-- README # 项目说明文件

Software Description 3.2 README

About the README, and this should be every project should have a file, the purpose is to be able to brief information of the project description, allowing readers to quickly understand the project. It should be noted that the following matters:

'''
1、软件定位,软件的基本功能;

2、运行代码的方法: 安装环境、启动命令等;

3、简要的使用说明;

4、代码目录结构说明,更详细点可以说明软件的基本原理;

5、常见问题说明。
'''

Guess you like

Origin www.cnblogs.com/Henry121/p/12592683.html