python学习-模块与包

'''
模块:包括了一系列功能的集合体

三种来源:1.内置的模块 2. 第三方的模块 3. 自定义模块
四种格式:
 1. 用python编写的.py文件
 2.已被编译为共享库或DLL的C或者C++扩展
 3. 一系列模块组织到一起的文件夹(主:文件夹下有一个__init__.py文件,该文件夹称之为包)
 4. 使用C编写并链接到python解释器的内置模块

为何要使用模块?
    1、使用自定义模块的好处:从文件级别组织程序,更方便管理,减少代码冗余
    2、使用内置或第三方模块的好处:拿来主义,提升开发效率
ps:
      如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,
    因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,
    此时test.py被称为脚本script。
'''

'''
使用模块(import的使用):
    1. import 模块名 导入模块
        总结:1.1在使用的时候必须以:模块名.名字的形式
              1.2 优点:指名道姓的像某一个名称空间要名字,不会与当前名称空间的名字冲突
              1.3 缺点:但凡调用都需要加上前缀,使用不够简洁
注:首次导入模块时:
    1.产生一个模块的名称空间
    2.执行模块文件,在执行过程中,将产生的名字变量传入名称空间的内存地址中 
    3.在执行文件中的到一个模块名,其指向模块文件的名称空间地址
之后的重复导入操作,都只是指向之前导入的结果地址,不会重新执行首次导入的三步操作4

    2.在文件中访问模块名称空间中名字的语法:模块名.名字
    例:time.x --------》寻找time模块文件中的x名字(或许是变量名,或许是函数名)

    3.一行多个模块同时导入(不推荐)
    例:import time,os.spam
    
    4.可以为模块起别名(注:模块名应该全为小写)
    例:import time as t
'''
'''
使用模块(from...import...):
    1.优点,使用时不需要加前缀,使用简洁
    2.缺点,易重名产生冲突,且后定义赋值 覆盖 前一个定义赋值的值
    3.取模块内全部名字(不推荐) from time import *
        *对于模块内__all__列表存储名字,若没有另外定义则返回所有名字(不包含_开头的变量名)
    4.起别名:from time import m as m1
    
注:首次导入模块时:
    1.产生一个模块的名称空间
    2.执行模块文件,在执行过程中,将产生的名字变量传入名称空间的内存地址中 
    3.在执行文件中直接拿到指定模块内的名字(或变量或函数)
    例: from time import x  取出了time模块的x名字
'''
'''
循环导入问题(test文件:m1,m2,run):
        模块的导入会在执行文件的时候创造名称空间,且仅一次
    如果执行步骤上python发现一家存在已创建的名称空间,则不会继续导入
    若执行文件在导入名字的时候被模块1内的导入模块2打断,则不会导入模块1的后续变量
    因为,python当检测到已经存在名称空间,则不会继续往名称空间内添加。
    
解决方法一:
        把循环导入的语句放到名字的下方
    原因:让执行文件导入模块1的时候,直接导入所有模块内名字,不会被模块1内的模块2导入打断

解决方法二:
        将循环导入语句放到函数内
    原因:不执行函数的时候,只检测函数语法而不运行函数
'''

'''
区别.py文件是执行文件还是模块文件(__name__):
    即:判断文件的__name__属性
        当文件被执行时(执行文件),__name__ == '__main__'
        当文件被导入时(模块文件),__name__ == '模块名'
注:(快捷方式) 输入main 自动提示 if __name__ == '__main__'
'''

'''
模块的搜索路径:

    模块搜索路径的优先级:
        1.内存中,已经加载过的
        2.内置模块
        3.sys模块中的path列表(sys.path),以当前执行文件所在文件夹绝对路径为首
        
强调:sys.path(环境变量)中的路径以执行文件的路径为准,包括被导入模块的环境变量
        (测试练习 环境变量测试文件夹内)
        
注:若找不到路径,解决方法:
    1.在执行文件中的sys.path内添加模块文件所在路径(处理环境变量),可以sys.path.append(绝对路径)
    2.(子文件夹)from 和执行文件同级的文件夹名 import 模块文件名
    3.(二级及以上子文件夹)from dir1.dir2 import m2 ---->dir1是dir2的父文件夹,m2位于dir2文件夹中
'''

'''
绝对导入和相对导入:

    绝对导入:以执行文件的sys.path为依据导入
        优点:执行文件和模块文件都可以使用
        缺点:所有导入都以sys.path为依据,导入麻烦
    
    相对导入:参照当前文件的文件夹为起始查找文件,称为相对导入
        符号:.代表当前所在文件,..代表上级文件夹,...代表上上级文件夹
            例:from . import m2 ; from .dir1 import m2
        优点:导入更加简单
        缺点:只能在被导入的模块中使用,不能在执行文件中使用
'''

'''
软件开发的目录规范:
    -ATM
        -bin
            -start.py
            
            #启动文件,即 main文件
            import sys,os
            BASE_DIR = os.path.dirname(os.path.dirname(__file__))
                #BASE_DIR 讲ATM项目文件夹路径加入环境变量
            sys.path.append(BASE_DIR)
            
            from core import db
                #导入核心逻辑模块 用于后续综合功能
            
            if __name__ = 'main' :
                db.run()
            #用于 执行判断
            
        -conf
            -setting.py
            
            #设置文件,用来保存全局使用的变量名
            import os
            BASE_DIR = os.path.DIRNAME(os.path.DIRNAME(__file__))
            DB_PATH=os.path.join(BASE_DIR,'db','db.json')
            LOG_PATH=os.path.join(BASE_DIR,'log','access.log')
            LOGIN_TIMEOUT=5
            .......
            
        -core
            -db.py
            #核心逻辑代码,不包括核心逻辑中存在的需求代码
            from conf import settings
            from lib import common
            import time
            
            def login():
                #登陆
                print('login')
                
            def register():
                #注册
                print('register')
            
            ...
            
        -db
            -db.json
            #数据库文件,用来保存用户登陆信息
            
        -lib
            -common.py
            #自定义模块,可用来辅助完成核心逻辑所需模块
            from conf import settings
            import logging
            import logging.config
            import json
            
            def get_logger(name):
                logging.config.dictConfig(settings.LOGGING_DIC)  # 导入上面定义的logging配置
                logger = logging.getLogger(name)  # 生成一个log实例
                return logger
            
            
            def conn_db():
                db_path=settings.DB_PATH
                dic=json.load(open(db_path,'r',encoding='utf-8'))
                return dic
                
                
        -log
            -access.log
            #按照setting文件中的格式,保存操作日志
            
        -readme.txt
            #项目解释文件
'''

'''
包:包就是一个包含有__init__.py文件的文件夹,本质是一种模块
创建包的目的:
    为了用文件夹将文件/模块组织起来
    
导入包的三部曲:
    1.以包下的__init__.py文件为基准来产生一个名称空间
    2.执行包下的__init__.py文件的代码,将执行过程中产生的名字都丢入名称空间
    3.在当前执行文件中拿到一个p1,p1指向__init__.py名称空间

导入包需要注意的问题:
    1.但凡是在 *导入语句* 中带点的,点的左边都必须是一个包
    2.包内部模块的绝对导入的起始位置都是以包的顶级目录为起始点
    3.包内部模块的导入通常应该使用 *相对导入* ,方便设计者对包顶级目录的修改操作
        .-本级    ..-上级   ...-上上级
        注意:
            1.*相对导入* 只能在包内部的模块之间互相导入
            2. ..上一级 不能超出顶级包
注意:
    1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错
        而在python2中,包下一定要有该文件,否则import 包报错
  2. 创建包的目的不是为了运行,而是被导入使用
        记住,包只是模块的一种形式而已,包的本质就是一种模块
    
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值