zoukankan      html  css  js  c++  java
  • 模块和包

     一.模块

       1.什么是模块

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

      2.模块的作用

      方便管理,使功能得到重复利用

      3.使用模块

          3.1 模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行,第一次导入后就已将模块名加载到内存中了。

       3.2 每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当作全局名称空间,编写自己的模块时不用担心与使用者的全局变量发生冲突。

          3.3 首次导入模块my_moudle时会做三件事:

       1.为源文件(my_moudle模块)创建新的名称空间,在my_moudle中定义的函数和方法若是使用到了global时访问的就是这个名称空间。

       2.在新创建的命名空间中执行模块中包含的代码,见初始导入import my_moudle

       3.创建名字my_moudle来引用该命名空间

       3.4 为模块起名 

    #import my_module as sm
    #print(sm.money)

       3.5 在一行中导入多个模块

    #import sys,os,re

       3.6 from...import

    #from my_module import read1,read2
    #这样可以直接用模块中的名字
    #如果当前文件中有和module中一样的名字比如都有read(),则会被覆盖

      注意:python中的变量赋值不是一种存储操作,而只是一种绑定关系

    #from my_moudle import money,read1
    #money=100 #将当前位置的名字money绑定到了100
    #print(money) #打印当前的名字
    #read1() #读取my_moudle.py中的名字money,仍然为1000
    
    '''
    #from the my_moudle.py
    #my_moudle->read1->money 1000
    '''

       3.7 支持as,也支持多行导入

    # from my_moudle import read1 as read
    
    # from my_moudle import (read1,
    #                 read2,
    #                   money)

      3.8 from my_moudle import * 把my_moudle中所有的不是以下划线(_)开头的名字都导入到当前位置,大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题。

    #from my_moudle import * #将模块my_moudle中所有的名字都导入到当前名称空间
    #print(money)
    #print(read1)
    #print(read2)
    #print(change)
    
    
    #执行结果:
    #from the my_moudle.py
    #<function read1 at 0x1012e8158>
    #<function read2 at 0x1012e81e0>
    #<function change at 0x1012e8268>
    #在my_moudle.py中新增一行
    
    #__all__=['money','read1'] 
    #这样在另外一个文件中用from my_moudle import *就这能导入列表中规定的两个名字

      3.9考虑到性能的原因,每个模块只被导入一次,放入字典sys.module中,如果你改变了模块的内容,你必须重启程序,python不支持重新加载或卸载之前导入的模块

    #def func1():
    #    print('func1')
    
    #import time,importlib
    #import aa
     
    #time.sleep(20)
       # importlib.reload(aa) #ctrl + s 可以更改
    #aa.func1()

      4.0把模块当作脚本执行

      我们可以通过模块的全局变量__name__来查看模块名:
      当做脚本运行:
      __name__ 等于'__main__'

      当做模块导入:
      __name__= 模块名

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

    def fib(n):   
        a, b = 0, 1
        while b < n:
            print(b, end=' ')
            a, b = b, a+b
        print()
    
    if __name__ == "__main__":
        print(__name__)
        num = input('num :')
        fib(int(num))

      4.1 模块搜索路径

       内存中已经加载的模块->内置模块->sys.path路径中包含的模块

       4.2 编译python文件

      为了提高模块的的加载速度,python解释器会在__pycache__目录中下缓存每个模块编译后的版本,格式为:module.version.pyc。通常会包含python的版本号。例如,在CPython3.3版本下,my_moudle.py模块会被缓存成__pycache__/my_moudle.cpython-33.pyc。这种命名规范保证了编译后的结果多版本共存。

    二.包

       2.1

      1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

      2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

      3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

      强调:

      1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

      2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

      2.2

      注意:

         1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。

         2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

         3.对比import item 和from item import name的应用场景:
        如果我们想直接使用name那必须使用后者。

       2.3 from ..import ...

     需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

      2.4 __init__.py文件

       不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。

  • 相关阅读:
    maven打包时出现 Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project……
    maven+springmvc出现:java.sql.SQLException: Unknown system variable 'query_cache_size'
    IDEA复制某个类的包名路径
    IDEA中更改Tomcat服务器的URL
    IDEA去除自动检测bean是否存在
    ASM ClassReader failed to parse class file
    The content of element type "web-app" must match "(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet- mapping*,session-config?,mime-map
    Could not open ServletContext resource [/WEB-INF/xxx-servlet.xml]
    Eclipse+maven 构建第一个简单的springmvc项目
    Eclispe中编辑xml配置文件时不会提示也不能自动调整格式
  • 原文地址:https://www.cnblogs.com/sxh-myblogs/p/7327238.html
Copyright © 2011-2022 走看看