• python—-模块与包1


    模块与包

    1 什么是模块?

     一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀

    2 为何要使用模块?

    如果你对出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script

    3 如何使用模块?

    实例文件:spam.py ,文件名spam.py ,模块名spam

     print("from the spam.py")
    money=1000
     def read1():
        print("spam-->read1-->money,money")
     def read2():
        print("spam-->read2-->")
        read1()
     def change():
         global money
         money=0
    

    3.1.1 模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行
             python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句
    import spam  #只在第一次导入时才执行spam.py内代码,
                 # 此时的显示效果是只打印一次“from the spam.py"
    import spam
    import spam
    import spam
    
    执行结果为:
    from the spam.py
    

     3.1.2 每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个函数的名称空间当做全局名称空间。

             这样我们在编写自己的模块时,就不用担心我们在定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突
    #测试一:money与spam.money 不冲突
    #test.py
    import spam
    money=100
    print(spam.money)
    
    执行结果:
    from the spam.py
    1000
    
    
    
    #测试二:read1与spam.read1 不冲突
    #test.py
    import spam
    def read1():
        print("read1")
    spam.read1()
    
    执行结果:
    from the spam.py
    spam-->read1-->money,money
    

      

    #测试三:执行spam.change()操作的全局变量money仍然是spam中
    #test.py
    import spam
    money=10
    spam.change()
    print(money)
    
    执行结果:
    from the spam.py
    10
    
    总结:导入模块会执行文件

     第一件事:创建名称空间,用来存放spam.py中定义的名字

     第二件事:基于刚刚创建的名称空间来执行spam.py

     第三件事:创建名字spam指向该名称空间,spam.名字的操作,都是以spam.py为准

      

    3.1.3 为模块名起别名,相当于m1=1;m2=m1

    import spam as sm
    print(sm.money)
    
    执行结果:
    from the spam.py
    1000
    

      

    3.1.4 在一行导入多个模块

    import sys,os,re
    

      

    3.2 from ……import…..

    3.2.1 对比import spam,会将源文件的名称空间“spam”带到当前名称空间时,使用时必须是spam.名字的方式。

               而from语句相当于import。也会创建新的名称空间,但是将spam的名字直接导入到当前的名称空间中,在当前的名称空间中,直接使用名字就可以了

    from spam import read1,read2

    这样在当前位置直接使用read1和read2就好了,执行时,仍然以spam.py文件全局名称空间

    #测试一:导入的函数read1,执行时仍然回到spam.py中寻找全局变量money
    #test.py
    from spam import read1
    money=1000
    read1()
    
    执行结果
    from the spam.py
    spam-->read1-->money,money
    

      

    #测试二:导入的函数read2,执行时需要调用read1(),仍然回到spam.py中找read()
    #test.py
    from spam import read2
    read2()
    
    执行结果
    from the spam.py
    spam-->read2-->
    spam-->read1-->money,money  

    如果当前有重名read1或者read2,那么会有覆盖效果

    #测试三:导入的函数read1,会被当前位置定义的read1覆盖掉
    #test.py
    from spam import read1
    def read1():
        print("----->")
    read1()
    
    执行结果
    from the spam.py
    ----->
    

    需要特别强调的一点是:python中的变量赋值不是一种存储操作,而只是一种绑定关系

    from spam import money,read1
    money=100
    print(money)
    read1()
    
    执行结果为:
    from the spam.py
    100
    spam-->read1-->money,money
    

       

    3.2.2 也支持as

    form spam import read1 as read
    

      

    3.2.3 支持导入多行

    from spam import (read1,
                    read2,
                    money)
    

      

    3.2.4 from spam import * 与__all__ * 控制来使用

    在spam.py中新增一行

    _all_=["money","read1"] #字符串形式

    #test.py
    from spam import * #不建议去用,避免重名
    print(money)
    print(read1)
    
    执行结果
    from the spam.py
    1000
    <function read1 at 0x02543390>
    

      

    3.3 把模块当做脚本执行 

    我们通过模块的全局变量__name__来看模块名

    当做脚本运行:

    __name__等于”__main__”

    当做模块导入:

    __name__

    print(__name__)
    #test.py
    import spam
    
    执行结果
    spam

    作用:用来控制.py文件在不同的应用场景下执行不同的逻辑

    if __name__ == '__main__':
        print("文件当做脚本去执行")
    
    执行结果
    文件当做脚本去执行
    

      

    3.4 模块搜索路径

    结模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

    import spam #先找内存:sys.modules-----》再找内建-----》最后找sys.path 

    在初始化后,python程序可以修改sys.path 路径放到前面优先于标准库被加载

    import sys
    sys.path.append(r'F:\python_fullstack_s4\day35\模块')
    sys.path.insert(0,r'F:\python_fullstack_s4\day35\模块') #排在前面的目录,优先被搜索
    

      

     
  • 相关阅读:
    hdu 5115 Dire Wolf 区间DP
    泛型兼容的注意事项
    maven web项目不能创建src/main/java等文件夹的问题
    error the @annotation pointcut expression is only supported at Java 5
    HashSet重复元素判断
    oracle 分库分表(sharding)
    关系型数据库分库分表解决方案
    JDK7中匿名内部类中使用局部变量要加final,JDK8中不需要,但jdk会默认加上final
    eclipse中更改配置使得switch语句不出错
    java io流中怎么在一个文本中追加字符串
  • 原文地址:https://www.cnblogs.com/niejinmei/p/6798048.html
Copyright © 2020-2023  润新知