[012]Python的函数_模块和包_全栈基础

您好!此笔记的文本和代码以网盘形式分享于文末!

因个人能力有限,错误处欢迎大家交流和指正!基础部分内容简单,但多且零散!

python之路——模块和包
模块定义:模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py
import加载的模块分为四个通用类别:
        1 使用python编写的代码(.py文件)
  2 已被编译为共享库或DLL的C或C++扩展
  3 包好一组模块的包
  4 使用C编写并链接到python解释器的内置模块
模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行
每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突
为源文件(my_module模块)创建新的名称空间,在my_module中定义的函数和方法若是使用到了global时访问的就是这个名称空间。
.在新创建的命名空间中执行模块中包含的代码,见初始导入import my_module
用法 栗子 结果
mymodule代码 print('from the my_module.py')

money = 1000


def read1():
    print('my_module->read1->money',money)


def read2():
    print('my_module->read2 calling read1')
    read1()


def change():
    global money
    money = 0
 
模块的独立名称空间 # 模块测试
import mymodule

# 变量、函数的独立名称空间
money = 10
print(money)
print(mymodule.money)
print(money)

mymodule.change()
print(money)
print(mymodule.money)


# 函数名相同测试
def read1():
    print('======')


mymodule.read1()
read1()
from the my_module.py
10
1000
10
10
0
my_module->read1->money 0
======
模块的别名 # 模块别名
import mymodule as mym

print(mym.money)
from the my_module.py
1000
据用户输入选择模块 # 根据输入选择不同的模块
db_type = input('mysql or oracle: ')
if db_type == 'mysql':
    import mysqltest as db
elif db_type == 'oracle':
    import oracletest as db

db.sqlparse()
mysql or oracle: mysql
from mysql sqlparse
选择读取不同的模块 # if file_format == 'xml':
#      import xmlreader as reader
# elif file_format == 'csv':
#      import csvreader as reader
# data = reader.read_date(filename)
 
一行中导入多个模块 # 一行中导入多个模块
# import sys,os,re
 
from导入
仍然是使用模块的
命名空间
# from 导入
from mymodule import read1
money = 15
read1()
from the my_module.py
my_module->read1->money 1000
from导入
函数调用
仍然是使用模块中的函数
from mymodule import read2


def read1():
    print('********')


read2()
from the my_module.py
my_module->read2 calling read1
my_module->read1->money 1000
覆盖关系 from mymodule import read1


def read1():
    print('********')


read1()
from the my_module.py
********
变量赋值的绑定关系 from mymodule import money, read1
money = 100  # 将当前位置的名字money绑定到了100
print(money)  # 打印当前的名字
read1()  # 读取my_module.py中的名字money,仍然为1000
from the my_module.py
100
my_module->read1->money 1000
from导入的重命名
和导入多个
# 支持as
from mymodule import read1 as read
# 支持导入多行
from mymodule import (read1, read2, money)
 
from my_module import *  把my_module中所有的不是以下划线(_)开头的名字都导入到当前位置 缺点:造成误覆盖和可读性差
from my_module import *  优化 __all__=['money','read1'] #这样在另外一个文件中用from my_module import *就这能导入列表中规定的两个名字  
模块的循环引用    
模块的加载与修改 def func1():
    print('func1')

import time,importlib
import aa
 
time.sleep(20)
# 等待期间修改aa.py中的内容
# importlib.reload(aa)
aa.func1()
 
将模块作为脚本执行 当做脚本运行:
__name__ 等于'__main__'
当做模块导入:
__name__= 模块名
def fib(n):  
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

if __name__ == "__main__":
    print(__name__)
    num = input('num :')
    fib(int(num))
 
模块搜索路径    
查找模块中定义的名字 import my_module
dir(my_module)
3.4  模块的搜索路径
编译python文件:为了提高加载模块的速度,解释器会在__pycache__目录中下缓存每个模块编译后的版本.pyc文件
你可以使用-O或者-OO转换python命令来减少编译模块的大小
     - O 转换会帮你去掉assert语句

-OO转换会帮你去掉assert语句和__doc__文档字符串
在速度上从.pyc文件中读指令来执行不会比从.py文件中读指令执行更快,只有在模块被加载时,.pyc文件才是更快的
dir()不会列举出内建函数或者变量的名字 import builtins
dir(builtins)
 
包是一种通过使用‘.模块名’来组织python模块名称空间的方式。
凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
在python3中,即使包下没有__init__.py文件,import 包仍然不会报错
创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块
模块  最重要是 自定义模块
包的绝对路径和相对路径
包的引用和 特点
用法 栗子 结果
创建一个包 # 创建包
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/__init__.py', 'w'))
l.append(open('glance/db/models.py', 'w'))
map(lambda f: f.close(), l)
 
import 用法 # 当前文件与glance同级别的中测试
import glance.db.models
glance.db.models.register_models('mysql')

from models.py:  mysql
form import 用法 # import导入的模块明确且不能带点
from glance.db import models
models.register_models('mysql')

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

from models.py:  mysql
from models.py:  mysql
__init__.py文件 # __init__.py文件 第一次导入包或者是包的任何其他部分,
# 都会依次执行包下的__init__.py文件
# 修改glance下 init文件 查看执行
from glance.db import models
models.register_models('mysql')
form glance __init__.py File
from models.py:  mysql
from glance.api import * 的用法 # 该语句只会导入包api下__init__.py文件中定义的名字,
# 可以在这个文件中定义__all___
"""
#在api文件夹下__init__.py中定义
x=10

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

__all__=['x','func','policy']
"""
# 使用import * 的用法 但是versions 依然是不能使用的
from glance.api import *
policy.get()
form glance __init__.py File
from policy.py
 绝对导入和相对导入 # 绝对导入和相对导入
"""
包内文件互掉,
注意事项和优缺点
    绝对导入:以glance作为起始
    相对导入:用.或者..的方式最为起始
    (只能在一个包中使用,不能用于不同目录内)
"""
# 在glance/api/version.py 文件中
# # 绝对导入
# from glance.cmd import manage
# manage.main()
#
# # 相对导入
# from ..db import models
# models.register_models('db')
# 测试结果 与glance同级文件
from glance.api import versions
# # 导入自定义的子模块时,应该使用form……import
# # 绝对或者相对导入,且包的相对导入只能用from的形式。
form glance __init__.py File
from manage.py
from models.py:  db
绝对路径问题 看视频  欠  
相对路径问题 看视频  欠  
单独导入包 # 单独导入包
# 单独导入包名称时不会导入包中所有包含的所有子模块
import glance
glance.cmd.manage.main()
form glance __init__.py File
Traceback (most recent call last):
  # 解决办法
"""
#在glance/__init__.py中添加
from . import cmd

#在glance/cmd/__init__.py中添加
from . import manage
"""
import glance
glance.cmd.manage.main()
form glance __init__.py File
from manage.py
python软件开发
目录结构规范
# python软件开发目录结构规范
import os
# bin/  存放项目的一些可执行文件
os.makedirs('soft/bin')
# conf/  配置文件
os.makedirs('soft/conf')
# core/  存放项目的所有源代码(核心代码)
# 1>源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。
os.makedirs('soft/core')
# core/tests/ 子目录 存放单元测试代码;
os.makedirs('soft/core/tests')
# db/ 数据库文件
os.makedirs('soft/db')
# lib/ 库文件,放自定义模块和包
os.makedirs('soft/lib')
# log/ 日志文件
os.makedirs('soft/log')
# docs/ 存放一些文档
os.makedirs('soft/doc')

l = []

# README 是项目说明文件
l.append(open('soft/README', 'w'))
l.append(open('soft/__init__.py', 'w'))
 [012]Python的函数_模块和包_全栈基础
  # start 写启动程序
l.append(open('soft/bin/start.py', 'w'))
l.append(open('soft/bin/__init__.py', 'w'))

# setting 写相关配置
l.append(open('soft/conf/setting.py', 'w'))
l.append(open('soft/conf/__init__.py', 'w'))
# my_log_setting 存放logging配置文件
l.append(open('soft/conf/my_log_setting.py', 'w'))
# config.ini 存放配置文件
l.append(open('soft/conf/config.ini', 'w'))
# main 程序的入口,存放核心逻辑代码
l.append(open('soft/core/main.py', 'w'))
l.append(open('soft/core/__init__.py', 'w'))

# 存放单元测试代码
l.append(open('soft/core/tests/test.main.py', 'w'))
l.append(open('soft/core/tests/__init__.py', 'w'))

# 写数据库文件
l.append(open('soft/db/db.json', 'w'))

# 存放常用功能
l.append(open('soft/lib/common.py', 'w'))
l.append(open('soft/lib/__init__.py', 'w'))

# 存放日志
l.append(open('soft/log/all.log', 'w'))
map(lambda f: f.close(), l)
 

愿有更多的朋友,在网页笔记结构上分享更逻辑和易读的形式:

链接:暂无
提取码:暂无