python入门day17——模块、循环导入、区分python文件、模块的搜索路径与查找优先级、命名规范

模块

什么是模块

       模块就是一个功能的集合体,不是用来直接运行,而是用来被导入使用的

模块三大来源

       1 内置的模块
       2 第三方模块
       3 自定义的模块

模块的四种形式

       1 使用python编写的.py文件一个python文件本身就一个模块,文件名m.py,模块名叫m
       2 把一系列模块组织到一起的文件夹(注:文件夹下有一个_init_.py文件,该文件夹称之为包)
       3 已被编译为共享库或DLL的C或C++扩展
       4 使用C编写并链接到python解释器的内置模块

为何有用模块

       1 使用别人的模块:内置与第三的模块拿来就用,无需定义,这种拿来主义,可以极大地提升自己的开发效率
       2 自定义的模块:可以将程序的各部分功能提取出来放到一模块中为大家共享使用。好处是减少了代码冗余,程序组织结构更加清晰

导入模块发生的事情

       1、触发被导入的模块的运行,产生一个模块的名称空间,把模块的名字都丢进去
       2、会在当前执行文件中得到一个名字spam,该名字是指向被导入模块产生的名称空间

       之后的导入,都是直接引用首次导入产生的spam.py名称空间,不会重复执行代码

# spam.py
print('from the spam.py')

__all__ = ['money', 'read1']

money = 1000


def read1():
    print('spam模块:', money)


def read2():
    print('spam模块')
    read1()


def change():
    global money
    money = 0
# txst.py
import spam
import spam
import spam  # 多余的import 不会执行
print(spam.money)



money = 2000
print(money)
print(spam.money)

spam.read1()

       一行导入多个模块
       如:import spam,m1,m2,m3
       如:from spam import money,read1

       为导入的模块起别名
       如:import dasasdsdfswads as
       如:from spam import read1 as f1

       自定义模块的命名应该采用纯小写+下划线的风格

       可以在函数内导入模块
       def func():
              import foo

import和from import差别

       Import时不会和本地的文件中的变量函数名冲突,模块名,就能使用,但是这种方法会一次性导入该模块中所有的,比较占内存

       from+Import 直接使用变量函数名就可以,但是如果本地文件中有相同的名字会发生冲突,一般注意一点就没问题,想用什么导入什么, 相比上面的会节约许多内存

# 使用上面的spam.py
from spam import read1,read2,money  # 没有change  所以下面运行change会报错


print(money)
read1()
print(read1)
print(read2)

money=111
print(money)
read1()

# read2 = 3333   read2替换了上面的spam.read2
# read2()  # 报错 替换的read2 不是函数

# change()  #报错  因为上面form导入没有change()

from spam import *  # 先把上面代码全注释了  *代表取spam中所有名字
# 在spam中添加__all__ = ['money', 'read1']  *就只取这两个 取不到read2、change 运行报错

print(money)
print(read1)
print(read2)  # 报错
print(change)  # 报错

循环导入问题

#示范文件内容如下
#m1.py
print('正在导入m1')
from m2 import y

x='m1'

#m2.py
print('正在导入m2')
from m1 import x

y='m2'

#run.py
import m1

#测试一
执行run.py会抛出异常
正在导入m1
正在导入m2
Traceback (most recent call last):
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/aa.py", line 1, in <module>
    import m1
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
    from m2 import y
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m2.py", line 2, in <module>
    from m1 import x
ImportError: cannot import name 'x'

#测试一结果分析
先执行run.py--->执行import m1,开始导入m1并运行其内部代码--->打印内容"正在导入m1"
--->执行from m2 import y 开始导入m2并运行其内部代码--->打印内容“正在导入m2”--->执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错


#测试二:执行文件不等于导入文件,比如执行m1.py不等于导入了m1
直接执行m1.py抛出异常
正在导入m1
正在导入m2
正在导入m1
Traceback (most recent call last):
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
    from m2 import y
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m2.py", line 2, in <module>
    from m1 import x
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
    from m2 import y
ImportError: cannot import name 'y'


#测试二分析
执行m1.py,打印“正在导入m1”,执行from m2 import y ,导入m2进而执行m2.py内部代码--->打印"正在导入m2",执行from m1 import x,此时m1是第一次被导入,执行m1.py并不等于导入了m1,于是开始导入m1并执行其内部代码--->打印"正在导入m1",执行from m1 import y,由于m1已经被导入过了,所以无需继续导入而直接问m2要y,然而y此时并没有存在于m2中所以报错

解决方法

方法一:导入语句放到最后
#m1.py
print('正在导入m1')

x='m1'

from m2 import y

#m2.py
print('正在导入m2')
y='m2'

from m1 import x

方法二:导入语句放到函数中
#m1.py
print('正在导入m1')

def f1():
    from m2 import y
    print(x,y)

x = 'm1'

# f1()

#m2.py
print('正在导入m2')

def f2():
    from m1 import x
    print(x,y)

y = 'm2'

#run.py
import m1

m1.f1()

区分python文件的两种用途

       1、直接运行。脚本,一个文件就是整个程序,用来被执行
       2、被当做模块导入。模块,文件中存放着一堆功能,用来被导入使用
print(_name_) # 当文件被当做脚本执行时,__name__值为’_main_
print(_name_) # 当文件被当做模块导入时,__name__值为’模块名’

# aaa.py
print('__name__')  # 当在该文件下运行时  出现的是__main__

# 作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
# main+回车键 会直接出现if __name__ == '__main__':
if __name__ == '__main__':
    print("文件被当作脚本执行时要做的事情")
# __main__
# 文件被当作脚本执行时要做的事情
# bbb.py
import aaa  
# 该文件下运行时 会出现main
# main

模块的搜索路径与查找优先级

       无论是import还是from…import在导入模块时都涉及到查找问题
       优先级:
       1、内存(内置模块)
       2、硬盘:按照sys.path中存放的文件的顺序依次查找要导入的模块
       模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

模块的搜索路径

1)先从内存中已经导入的模块里找

# mmm.py中写着
# def f1():
#     print('mmm.f1')

mmm
mmm.f1()

import time
time.sleep(15)
print('='*50)
# 将mmm.py删了 还是能找到 因为还在内存中
import mmm
mmm.f1()

2)然后再查找内置的模块

# import time  # 内置模块
# print(time)
#
import sys
# print(sys.modules)  # 查看已有的内置模块 sys.modules查看已经加载到内存中的模块

print(sys.path)  # sys.path是一个python搜索模块的路径列表:


# 当前执行文件所在的文件夹
import logging
print(logging)

3)最后去sys.path列表中存放的多个文件夹依次检索

示例1:
import sys
# 找bbb.py就把bbb.py的文件夹添加到环境变量中
# bbb.py在day17.aaa.ccc中
sys.path.append(r'/Users/gj/Desktop/pycharm_space/s15/day16/aaa/ccc')
# 可以是其他路径 不需要同一个文件下
import bbb
bbb.f1()

from mmm import f1

# 示例2:
import sys
print(sys.path)
import day17.aaa.ccc.bbb as b
# 同一个根目录 文件夹下
b.f1()

from aaa.ccc import bbb  # aaa和该文件在同一个根目录
bbb.f1()

python命名规范

PYTHON命名规范
1.项目名称
首字母大写+大写式驼峰,
ProjectName

2.模块名和包名
全部小写+下划线驼峰
module_name package_name

3.类名称,异常
首字母大写+大写式驼峰,
class ClassName: ,ExceptionName

4.全局变量、常量
全部使用大写字母+下划线驼峰
GLOBAL_VAR_NAME,CONSTANT_NAME

5.方法名,函数名,其余变量,参数,实例
全部小写+下划线驼峰
method_name,function_name,instance_var_name, function_parameter_name, local_var_name

6.处理计数器外,不使用单字母命名

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值