• Python-模块


    定义:略!

    先来一个模块spam.py

    #spam.py
    print('from the spam.py')
    
    money=1000
    
    def read1():
        print('spam模块:',money)
    
    def read2():
        print('spam模块')
        read1()
    
    def change():
        global money
        money=0
    spam.py

    import spam    (从硬盘将spam读到内存中,执行一遍)

    导入后,从上至下执行模块内部所有的代码。

    结果是:from the spam.py

    但是,在第二次导入的时候,就不用在执行模块里面的代码了。因为之前该模块已经加载过。

    import spam #m1=111111
    import spam #m2=m1
    import spam
    import spam

    总结:

    # 导入模块,只会在第一次导入时执行源文件的代码
    # 如果模块已经加载到内存了,下一次导入直接引用内存中导入的结果

    下面看内存当中都加载了哪些模块:

    import sys
    print(sys.modules)
    print('spam' in sys.modules)

    字典形式列出;里面有上面的spam模块,因为spam之前已经加载完成了。

    接下来,名称空间:

    运行一个执行文件就会产生一个名称空间。import后又产生一个名称空间,至此这个“模块的使用.py”执行文件产生了两个名称空间,且两个内存空间是互相独立的。

    #import 导入文件都做了哪些事?
    #1 以源文件(spam.py)为准产生一个名称空间
    #2 以刚刚产生的名称空间为准,执行源文件的代码
    #3 会在当前文件中(执行文件)定义一个名字(模块名),这个名字就是模块名,用来指向模块所在的名称空间,即可以调用里面的功能
    import spam
    money=0
    spam.read1()
    
    结果:
    from the spam.py
    spam模块: 1000

    类似:

    import spam
    money=0
    def read1():
        print('from ------>')
    spam.read1()

    下面这么写才能调用当前位置的read1

    import spam
    money=0
    def read1():
        print('from ------>')
    read1()
    spam.read1()

    再如:

    import spam
    money=0
    def read1():
        print('from ------>')
    # read1()
    # spam.read1()
    spam.read2()

    这里仍然执行spam里的read1

    再如:

    import spam
    money=0
    money=1000000000
    spam.change()
    print(money)
    
    结果:
    from the spam.py
    1000000000

    这里change的是spam的money值。

    import spam
    money=0
    money=1000000000
    spam.change()
    # print(money)
    spam.read1()
    
    结果:
    from the spam.py
    spam模块: 0

    这样可以看出change模块内部money值成功。

    下面:

    为模块起别名----

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

    也可以调用除了函数的其他变量

    好处:

    # 1、简化模块名称;
    # 2、调用方便,例子如下:
    前提:两个模块,一个是mysql.py,另一个是oracle.py。
    mysql.py代码如下:
    def parse():
        print('mysql sql parse')
    
    oracle.py代码如下:
    def parse():
        print('oracle sql parse')
    
    就可以简化成如下:
    engine_type='mysql'
    if engine_type == 'mysql':
        import mysql as engine
    elif engine_type == 'oracle':
        import oracle as engine
    
    engine.parse()
    别名优点

    另外,在一行导入多个模块

    import spam,time

    导入模块的另一种方法:

    from...import...

    好处是,在当前执行文件中用模块里的变量或函数的时候不用加.了。直接用变量或函数即可,不用再加前缀

    坏处是,容易个当前文件里的名字冲突。

    from spam import money,read1,read2,change
    # money=1
    print(money)
    
    结果:
    from the spam.py
    1000
    
    from spam import money,read1,read2,change
    money=1
    print(money)
    
    结果:
    from the spam.py
    1

    注意:不加前缀,优先从当前位置找变量或者函数。

    from spam import money,read1,read2,change
    # money=1
    # print(money)
    read1()
    def read1():
        print('===>?')
    
    结果:
    from the spam.py
    spam模块: 1000

    哈哈,再注意:代码顺序;这里执行函数read1的时候,当前还没有定义好的read1函数,当前read1函数在后面了!

    from spam import money,read1,read2,change
    # money=1
    # print(money)
    read1()
    def read1():
        print('===>?')
    # read1()
    read2()

    read2调用的read1仍然是spam里的read1

    from spam import money,read1,read2,change
    money=1
    change()
    print(money)
    
    结果:
    from the spam.py
    1

    print的仍然是当前文件定义的变量。

    导入模块中的函数太多怎么办?

    from spam import *
    print(money)
    print(read1)
    print(read2)
    print(change)
    
    结果:
    from the spam.py
    1000
    <function read1 at 0x101c62510>
    <function read2 at 0x101c62620>
    <function change at 0x101c626a8>
    *方案

    导入模块中的全部变量,引起冲突的可能性更大,而且有的属性可能用不到,尽量少用。

    Python模块内置变量__all__,列表形式,里面都是字符串(对应变量名、函数名等)

    __all__=['money','read1'] #from ... import *
    
    这样,*代表只导入了'money','read1'两个函数

    * 对应模块spam内的__all__属性

    如果被导入的模块没有__all__,*导入所有变量,如果被导入的模块有__all__。就以这个__all__后面的为准。

    from也支持as

    from spam import read1 as read

    模块的重载:

    程序需要重新启动才能利用改过的的模块程序。 也就是从硬盘读取新的内容加载到内存中。

    不过,实验环境可以:

    import importlib
    importlib.reload()

    重新加载更新的模块。

    需要在每个程序(需要使用更新后的模块)文件中重新加载。

    py文件区分两种用途:模块与脚本

    python文件都内置__name__

    脚本时(spam):
    print(__name__)
    
    spam执行结果:
    from the spam.py
    __main__

    如果,在执行文件中,import spam

    spam里的加入print(__name__)

    执行文件执行结果是

    from the spam.py
    spam

    总结:文件spam.py当做脚本执行,该值等于__main__,文件spam.py当做模块被导入时,该值等于spam

    spam中加入:
    if
    __name__ == '__main__': read1() read2() change() spam执行结果: from the spam.py spam模块: 1000 spam模块 spam模块: 1000

    如果在执行文件中执行,就只有导入模块

    import spam
    
    结果:
    from the spam.py

    作者:大雄猫
    出处:http://www.cnblogs.com/guoxiangqian/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面 明显位M给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    大家帮忙出几个招聘考试题目吧
    单元测试和设计模式在重构中的应用
    想起去年和女朋友第一次去吃饭的事情
    为什么我们常忘记使用正则表达式
    .NET实用设计模式:观察者模式(Observer)
    一个Outlook宏写的小程序,献给象我一样粗心大意的人
    单元测试应该测什么,不应该测什么?
    .NET实用设计模式:工厂模式(Factory)
    2021 系统架构设计师备考分享
    系统架构设计师论文企业集成
  • 原文地址:https://www.cnblogs.com/guoxiangqian/p/7694704.html
Copyright © 2020-2023  润新知