漫天飞雪

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
*1 什么是模块*
    模块就是一系列功能的集合体
        模块有三种来源

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

        模块的格式:
          1 使用python编写的.py文件(常用)
          2 已被编译为共享库或DLL的C或C++扩展
          3 把一系列模块组织到一起的文件夹(注:每一个包目录下面都会有一个*init*.py 的文件,这个文件是必须存在的,否则,Python 就把这个目录当成普通目录,而不是一个包。*init*.py 可以是空文件,也可以有 Python 代码,因为*init*.py 本身就是一个模块,而它的模块名就是 mycompany)
          4 使用C编写并链接到python解释器的内置模块

*2 为何要用模块*

    1. 使用内置的或者第三方模块的好处是: 拿来主义,可以极大提升开发效率
    2. 使用自定义模块的好处是: 可以减少代码冗余(抽取我们自己程序中要公用的一些功能定义成模块,然后程序的各部分组件都去模块中调用共享的功能)

*3 如何用模块*
    大前提: 一定要区分开谁是执行文件,谁是被导入模块

_*import*_


例:

#spam.py

money=1000

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

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

def change():
    global money
    money=0

文件名是spam.py,模块名则是spam

*首次导入模块发生3件事*

1. _会产生一个模块的名称空间_

2. _执行文件spam.py,将执行过程中产生的名字都放到模块的名称空间中_

3. _在当前执行文件的名称空间中拿到一个模块名,该名字指向模块的名称空间_
    _之后的导入,都是直接引用第一次导入的成果,不会重新执行文件_

    import spam

    # 之后引用的同名模块不会再重复执行

    import spam

    import spam

    import spam



*在执行文件中访问模块名称空间中名字的语法:模块名.名字*

import spam

print(spam.x) # 指名道姓地跟spam要名字x,肯定不会与当前执行文件中的名字冲突


*总结*

import导入模块:在使用时必须加上前缀:模块名.

优点: _指名道姓地向某一个名称空间要名字,肯定不会与当前名称空间中的名字冲突_

缺点: _但凡应用模块中的名字都需要加前缀,不够简洁_



* 一行导入多个模块(不推荐)

           import spam, os, time

* 可以为模块起别名(注意:模块名应该全为小写)

           import spam as sm


_form .. import .._

例:

#spam.py

__all__ = ['money','read1'] #from spam import *

money=1000

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

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

def change():
    global money
    money=0

money=200

*首次导入模块发生3件事*

1. _创建一个模块的名称空间_

2. _执行文件spam.py,将执行过程中产生的名字都放到模块的名称空间中_

3. _在当前执行文件中直接拿到一个名字,该名字就是执行模块中相对应的名字的_

from spam import money,read1,read2,change

money=200

print(money)

read1=123

read1()

read2()

change()

print(money)




*总结*

from...import...

优点: _使用时,无需再加前缀,更简洁_

缺点: _容易与当前名称空间中的名字冲突_

from spam import * 代表从被导入模块中拿到所有名字(不推荐使用)

# from spam import money,read1,read2,change
# from spam import  # *all* = ['money','read1']

print(money)

print(read1)

print(read2)

print(change)

起别名  from spam import read1 as r1

r1()

 

内容:
1. 模块的循环导入
2. 区分python文件的两种用途
3. 模块的搜索路径
4. 模块的绝对导入
5. 模块的相对导入
6. 软件开发的目录规范

'''
首次导入模块发生的三件事
1. 产生一个模块的名称空间
2. 执行被导入模块的代码,将产生的名字全都放在模块的名称空间里
3. 当执行文件时,拿到一个被导入模块的名字,这个名字就指向被导入模块的名称空间的那个名字
'''
*第二次再导入相同模块时,就直接引用第一次导入模块时的那个名称空间。*
*模块的循环导入*
m1.py
#m1
 print("from m1")
 from m2 import y
 x = "m1"

 m2.py
 #m2
 print("from m2")
 from m1 import x
 y = "m2"

 run.py
 import m1
*执行run程序 导入m1,执行到 from m2 import y 会去导入 m2 并且寻找y的内存地址,但是导入m2之后,*
*又执行了from m1 import x,这时候又会去回到m1中找x的内存地址,但是x这时候还没有被放入内存中,就会发生锁一样的东西,*
*程序就会报错。*

如何来解决循环导入,并解决第1题中的循环导入问题
方法一:
把x="m1"放到 from m2 import y 上面,就等于先把x放入到内存里,这时候继续往下执行,执行到m2中的from m1 import x的时候,
程序就找到x的内存地址。锁就自然就开了。
方法二:
将from m2 import y定义在函数里面,先放到内存中,这时候就会自然向下执行x="m1",将from m1 import x也定义为函数,
将函数的内存地址也给导入到m1中,也就是from m2 import y,f2 并且执行f2()
在主程序run里面调用m1中的函数f1,这时候就不会发生锁了


区分python文件的两种用途
*#当文件被执行时__name__=='__main__' (执行文件)*
*#当文件被导入时__name__=='模块名' (被导入的模块)*
*当加入 if __name__=='__main__':的时候*
*在这条语句下面的方法调用,只会在执行此文件时才会被调用,在其他文件里是运行不了的。*

要分清大前提:什么是执行文件,什么是被导入文件



模块的搜索路径
模块搜索路径的优先级:
*1. 内存中已经加载过的*
*2. 内置模块*
*3. Sys.path(环境变量)中的 第一个值是当前执行文件所在的文件夹* (pychram会添加一条当前目录的父目录,放在第二个位置,帮助我们识别一些其他的路径,可以让我们写程序的时候,可以用TAB键补齐语法)
# 环境变量是以当前执行文件为准的
# 强调:所有被导入的模块参照环境变量sys.path都是以执行文件为准的

*注:命名模块时,不可与内置模块的名字冲突*(模块搜索路径,内置的优先级比sys.path的高)

*模块的绝对导入:以sys.path为基准寻找模块的方式*
* 优点:执行文件与被导入的模块都可以使用*
* 缺点:所有的被导入的模块,都是参照执行文件的sys.path,导入麻烦 *

*模块的相对导入:参照当前文件的文件夹为起始位置开始查找,称之为相对导入。*
*优点:导入更加简单*
* 缺点:只能在被导入的模块中使用,不能再执行文件中使用。(执行文件只能用绝对导入)*

* 符号:. 表示当前文件所在文件的文件夹。. . 表示前文件所在文件的文件夹的上一级。. . .表示上一级的上一级文件夹*

比如有A,B,C三个文件
在A中导入B,如果想在B中导入C,模块的搜索路径是以A为准的。A是执行文件,B,C是模块

环境变量是以当前执行文件为准的,所有的被导入的模块,参照的sys.path都是执行文件的。(sys.path是个列表,里面有多个值)

Import sys.
Sys.path.append(r”路径”)可添加sys.path。

 *软件开发的目录规范*
*bin:放程序入口*
*conf:放配置文件*
*core:放业务逻辑的文件*
*db:放关于业务数据的文件*
*lib:放需要公共使用的包或模块*
*log:放日志文件*
*Readme:写关于软件的使用手册或一些介绍*

包的使用
1、在导入时带点的,点的左边必须是一个包,这是导入包特有的语法
2、包内,模块直接的导入应该使用from。。。import 。。。
3、from 。。。 import。。。,import后必须是一个明确的名字,没有任何的前缀

例如: from a.b.c.d.f import g.h.x #错误
1、f左边必须都是包
2、import后的名字不能有任何前缀
#模块名约定用全小写
#包内的模块没有右键运行的需求

2、格式化的字符串
print(time.strftime('%Y-%m-%d %H:%M:%S %p'))

 

posted on 2018-12-26 20:31  漫天飞雪世情难却  阅读(96)  评论(0编辑  收藏  举报