为了更好的开发、维护、管理项目,我们需要了解python中项目的组织结构。

1.组织结构

在python中最顶级的是(文件夹),包下面有模块(py文件),模块下面有。一个可以包含多个模块,一个模块可以包含多个类。

包
|--模块1
  |--类11
  |--类12
|--模块2
  |--类21
  |--类22

####示例

server
|--s1.py
|--s2.py
|--s3.py

2.包与模块命名

python包

一般命名包就是命名一个文件夹名称,包之间的区分就是通过不同的名称来区分的。包下面也可以有子包python是如何区分文件夹,在python中,如果定义一个python包,那么这个python包下面必须要有__init__.py文件,如果没有这个文件,python就认为这是一个文件夹而不是一个包。

__init__.py文件是声明这是一个python包,在__init__.py文件中可以什么都不写,也可以像其他*.py文件一样在里面声明变量、函数、类等。

server
|--__init__.py
|--demo #子包
   |--d1.py
|--s1.py
|--s2.py

python模块

python模块可以简单的认为是一个后缀为py的python文件。模块名就是文件的名称。

server
|--__init__.py
|--s1.py
|--s2.py
net
|--__init__.py
|--s1.py

对于上面两个不同包下面相同的模块名称,我们如何区分。在代码中,如果我们引入模块时,有两个相同的模块名称,那么我们需要再模块前面加上包名

# 导入server包下面 s1模块
import server.s1 

3.导入模块

improt 模块

在编写代码时,我们有时会需要其他模块的变量或者方法,那么如何导入其他模块的变量、方法呢?

文件结构

./
|-server
|--__init__.py
|--s1.py
|--s2.py

s1.py

a = 1

如何在s2.py模块中使用s1.py模块的变量

s2.py

import s1
print(s1.a)

使用as重新命名

import server.s1 as p

当导入的模块不是当前包中的同级模块时,在导入时需要添加包名包名.模块名

from import 模块

上面import是导入模块,form improt可以单独导入模块中的变量或方法,依旧用上面的例子举例

s2.py

- import s1
- print(s1.a)

+ from s1 import a
+ print(a)

from import不仅可以导入模块中的变量方法,也可以导入模块

#假设在net包下有个n1.py模块
from net import n1
# 从net包下面导入 n1模块

使用*导入模块全部变量

# 导入s1模块下面所有的变量
from s1 import *

一般是不建议导入模块的全部变量,可以在s1模块中设置

s1.py

__all__ = ['a','b']

a = 1
b = 2
c = 3

在s2.py模块中from s1 import *中就只会导入ab两个变量

4.__init__的用法

__init__.py是包的初始化文件,当包被导入时,首先加载执行__init__.py文件,是自动加载执行的。

批量导入模块

当多个模块中需要使用多个系统模块,如果在每个模块中导入相同的系统模块,就会显得比较繁琐。

server
|--net
  |--__init__.py
|--s1.py
|--s2.py

假设在s1s2中需要引入多个相同的模块时,可以在__init__.py中引入,然后在s1s2模块中分别导入net包就可以了

__init__.py

import sys
import datetime
import io

s1.py 和 s2.py

import net

5.包与模块几个常见错误

包与模块几个常见的错误:

6.内置变量

除了我们可以在模块中定义变量,模块中也会有系统内置变量。 查看模块里内置变量

a = 1
b = 2
info = dir()
print(info)

"""
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b']
"""

从上面打印出来的变量我们可以看到系统内置变量都是__开头和结尾的,最后ab变量是我们在文件中自定义的

变量描述
annotations注解
doc模块中的注释
file模块路径
name模块名称
package包的名称

7.入口文件和普通模块内置变量

文件结构

server
|--demo
  |--__init__.py
  |--s1.py
|--s2.py

s1.py

"""
    s1模块的注释
"""
print('=======================s1========================')
print('package: ' + (__package__ or '当前模块不属于任何包'))
print('name: ' + __name__)
print('doc: ' +  (__doc__ or '当前模块没有注释'))
print('file: ' + __file__)

s2.py

import demo.s1
print('=======================s2========================')
print('package: ' + (__package__ or '当前模块不属于任何包'))
print('name: ' + __name__)
print('doc: ' +  (__doc__ or '当前模块没有注释'))
print('file: ' + __file__)

运行s2模块

python s2.py

输出内容

================s1======================
package: demo
name: demo.s1
doc:
    s1模块的注释

file: C:\Users\Administrator\Desktop\py\server\demo\s1.py
=================s2==================
package: 当前模块不属于任何包
name: __main__
doc: 当前模块没有注释
file: s2.py

从打印的出的信息中可以看出,当python s2.py时,其实是把s2设置成python的入口文件,在入口文件中导入s1模块,s1是普通模块,s2是入口文件,可以对比一下输出的信息发现入口文件中package不属于任何包,且name不在是模块名称,而变成__mian__

__name__应用

在实际开发中我们可能需要区分入口文件还是普通模块来处理不同的逻辑代码

if __name__ == '__mian__':
    pass

8.相对导入和绝对导入

文件结构

demo
|--package1
   |--p1.py
   |--p2.py
|--package2
   |--p3.py
|--mian.py

顶级包和入口文件

python中顶级包是和入口文件目录级相同,我们看上面的文件结构,目录是demo,当运行python main.py,将main.py作为入口文件,此时顶级包就是package1、package2,而不是demo,要想将demo做为顶级包,就需要将mian.py放在和demo同级

入口文件:一般就是python 命令运行某个模块,但是也不一定,如果python -m 模块就是将这个python模块当做普通模块来运行。具体要判断是不是入口文件,还是要打印模块中内置变量 __name__看其是不是__name == '__main__'

注意:入口文件不允许使用相对路径,必须使用绝对路径

绝对路径

在python模块中,看到

# main.py
import package1.p2

这段代码import路径就是一个绝对路径,绝对路径在导入时,一定要从顶级包开始。

相对路径

python 中相对路径.表示当前目录,..表示上一层目录,...表示上上一层目录,然后依次类推。import只能写绝对路径,如果需要使用相对路径必须使用from import

# p3.py 
#入口文件依然是mian.py

#绝对路径 
import p1

#相对路径
from .p1 import m

python中相对路径之所以能够定位到模块是因为内置变量__name__,入口文件之所以必须使用绝对路径,是因为一旦被python认为是入口文件,那么__name__发生了改变。不能定位到模块,这就是为什么入口文件必须使用绝对路径

python3.7 入门教程

Python 准备工作(1) Python 基本数据类型 Number(2) Python 字符串 str(3) Python 列表List(4) Python 元组tuple(5) Python 集合set(6) Python 字典 dict(7) Python 变量(8) Python 运算符(9) Python 条件语句(10) Python 循环语句(11) Python 包 模块(12) Python 函数一(13) Python 函数二(14) Python 面向对象(15) Python 正则(16) Python json(17) Python 枚举(18) Python 闭包(19) Python 装饰器(20) Python 杂记(21) Python with(22)