模块_模块化 - CSDN
精华内容
参与话题
  • 什么是模块

    2019-07-25 00:59:13
    在计算机程序的开发过程中,随着程序代码越写越多,在一个...在Python中,一个.py文件就称之为一个模块(Module)。 使用模块有什么好处? 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始...

    在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。

    为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。

    使用模块有什么好处?

    1. 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
    2. 使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲模块分类

    模块分类

    模块分为三种:

    • 内置标准模块(又称标准库)执行help('modules')查看所有python自带模块列表
    • 第三方开源模块,可通过pip install 模块名 联网安装
    • 自定义模块

    模块调用

    import module
    
    from module import xx
    
    from module.xx.xx import xx as rename  
    
    from module.xx.xx import *

    包(Package)

    当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹,

    .
    └── my_proj
        ├── crm #代码目录
        │   ├── admin.py
        │   ├── apps.py
        │   ├── models.py
        │   ├── tests.py
        │   └── views.py
        ├── manage.py
        └── my_proj #配置文件目录
            ├── settings.py
            ├── urls.py
            └── wsgi.py
    

    像上面这样,一个文件夹管理多个模块文件,这个文件夹就被称为包

    那不同包之间的模块互相导入呢?

    crm/views.py内容

    def sayhi():
        print('hello world!')
    

    通过manage.py调用

    from crm import views
    
    views.sayhi()
    

    执行manage.py (注意这里用python2)

    Alexs-MacBook-Pro:my_proj alex$ ls
    crm        manage.py    my_proj
    Alexs-MacBook-Pro:my_proj alex$ python manage.py 
    Traceback (most recent call last):
      File "manage.py", line 6, in <module>
        from crm import views
    ImportError: No module named crm
    

    竟然说找不到模块,为什么呢?

    包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。

    在crm目录下创建一个空文件__int__.py ,再执行一次就可以了

    Alexs-MacBook-Pro:my_proj alex$ touch crm/__init__.py #创建一个空文件
    Alexs-MacBook-Pro:my_proj alex$ 
    Alexs-MacBook-Pro:my_proj alex$ ls crm/
    __init__.py    admin.py    models.py    views.py
    __pycache__    apps.py        tests.py    views.pyc
    Alexs-MacBook-Pro:my_proj alex$ python manage.py 
    hello world!
    

    注意,在python3里,即使目录下没__int__.py文件也能创建成功,猜应该是解释器优化所致,但创建包还是要记得加上这个文件 吧。

    跨模块导入

    目录结构如下

    .
    ├── __init__.py
    ├── crm
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── tests.py
    │   ├── views.py  
    ├── manage.py   
    └── proj
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py
    

    根据上面的结构,如何实现在crm/views.py里导入proj/settings.py模块?

    直接导入的话,会报错,说找到不模块

    $ python3 views.py
    Traceback (most recent call last):
      File "views.py", line 2, in <module>
        from proj import settings
    ModuleNotFoundError: No module named 'proj'
    

    是因为路径找不到,proj/settings.py 相当于是crm/views.py的父亲(crm)的兄弟(proj)的儿子(settings.py),settings.py算是views.py的表弟啦,在views.py里只能导入同级别兄弟模块代码,或者子级别包里的模块,根本不知道表弟表哥的存在。这可怎么办呢?

    答案是添加环境变量,把父亲级的路径添加到sys.path中,就可以了,这样导入 就相当于从父亲级开始找模块了。

    crm/views.py中添加环境变量

    import sys ,os
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #__file__的是打印当前被执行的模块.py文件相对路径,注意是相对路径
    print(BASE_DIR)
    
    sys.path.append(BASE_DIR)  
    
    from proj import settings
    
    def sayhi():
        print('hello world!')
    
    print(settings.DATABASES)
    

    输出

    $ python3 views.py
    /Users/alex/Documents/work/PyProjects/luffy_课件/21天入门/chapter4-常用模块/packages/my_proj
    ---my proj init---  #proj/__init__.py输出
    in proj/settings.py #proj/settings.py输出
    {'host': 'localhost'}
    

    *注意;此时在proj/settings.py写上import urls会有问题么?

    DATABASES= {
        'host':'localhost'
    }
    
    import urls  #这行刚加的 
    print('in proj/settings.py')
    

    结果报错了

    ModuleNotFoundError: No module named 'urls'
    

    为什么呢? 因为现在的程序入口是views.py , 你在settings.py导入import urls,其实相当于在crm目录找urls.py,而不是proj目录,若想正常导入,要改成如下

    DATABASES= {
        'host':'localhost'
    }
    
    from proj import urls  #proj这一层目录已经添加到sys.path里,可以直接找到
    print('in proj/settings.py')
    

    绝对导入&相对导入

    在linux里可以通过cd ..回到上一层目录 ,cd ../.. 往上回2层,这个..就是指相对路径,在python里,导入也可以通过..

    例如:

    .
    ├── __init__.py
    ├── crm
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── tests.py
    │   ├── views.py  #from ..proj import settings 
    ├── manage.py   
    └── proj
        ├── __init__.py
        ├── settings.py #from .import urls  
        ├── urls.py
        └── wsgi.py
    

    views.py里代码

    from ..proj import settings
    def sayhi():
        print('hello world!')
    
    print(settings.DATABASES)
    

    执行结果报错了

    Traceback (most recent call last):
    File "my_proj/crm/views.py", line 4, in <module>
     from ..proj import settings
    SystemError: Parent module '' not loaded, cannot perform relative import
    

    或者有人会看到这个错

    ValueError: attempted relative import beyond top-level package
    

    其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。

    文件夹被python解释器视作package需要满足两个条件:

    1. 文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
    2. 不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。

    所以这个问题的解决办法就是,既然你在views.py里执行了相对导入,那就不要把views.py当作入口程序,可以通过上一级的manage.py调用views.py

    .
    ├── __init__.py
    ├── crm
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── tests.py
    │   ├── views.py  #from ..proj import settings 
    ├── manage.py  #from crm import views 
    └── proj
        ├── __init__.py
        ├── settings.py #from .import urls  
        ├── urls.py
        └── wsgi.py
    

    事实证明还是不行,报错

    ValueError: attempted relative import beyond top-level package
    

    但把from ..proj import settings 改成from . import models 后却执行成功了,为什么呢?

    from .. import models会报错的原因是,这句代码会把manage.py所在的这一层视作package,但实际上它不是,因为package不能是顶层入口代码,若想不出错,只能把manage.py往上再移一层。

    正确的代码目录结构如下

        packages/
        ├── __init__.py
        ├── manage.py #from my_proj.crm  import views
        └── my_proj
            ├── crm
            │   ├── admin.py
            │   ├── apps.py
            │   ├── models.py
            │   ├── tests.py
            │   ├── views.py  #from . import models;  from ..proj import settings 
            └── proj
                ├── __init__.py
                ├── settings.py
                ├── urls.py
                └── wsgi.py
    

    再执行manage.py就不会报错了。

    注:虽然python支持相对导入,但对模块间的路径关系要求比较严格,处理不当就容易出错,so并不建议在项目里经常使用。

     

    转载于:https://www.cnblogs.com/hexiaorui123/p/10195432.html

    展开全文
  • # 一个文件就是一个模块,从文件物理的角度,从逻辑的角度说,一个模块也是存在命名空间中。 # 划分模块的好处: """ 1. 一个模块提供了一个独立的命名空间,解决命名冲突 2. 按照模块划分不同...

    第九章 模块和包

    “”"

    模块

    具体模块
    math包
    随机包
    时间日期包
    date类
    time类
    datetime类

    一、模块

     1.模块的定义
    
    import keyword
    print(keyword.kwlist)
    
     为什么要有模块:
     一个文件就是一个模块,从文件物理的角度,从逻辑的角度说,一个模块也是存在命名空间中。
     划分模块的好处:
    """
    1. 一个模块提供了一个独立的命名空间,解决命名冲突
    2. 按照模块划分不同功能,不同的功能在不同py文件开发。
    3. 提高代码的复用性
    """
     代码共享:svn  cvs  gitpub
    
    2. 模块的使用
     模块之间如何调用。
     两种方式,(1)import   (2) from...import...
     
     (1)import
         【导入语法】:import 要导入的模块名(如果有多个模块,用逗号分隔即可)
         当导入了一个模块之后,计算机python做了什么?
         当import一个模块(py),则会把被导入模块的代码执行一次。
         如果再次导入,则不会重复执行。
         习惯上,将导入全部放在代码的面前
        
         【使用导入模块的语法】:模块名.名称
         import math
         print(math.pow(3,4))
        
         导入自定义模块
         import another
         print(another.x)
         another.y()
          使用import,会避免名字冲突,因为使用导入模块的名字,前面要有  模块名.
         x=1
         print(x)
    
    
    (2) from 模块名 import 名字
         【导入的语法】 from 模块名 import 名字1,名字2
         from...import跟import类似,在导入的时候,被执行被导入模块的代码
         【使用导入模块的名字语法】
        直接使用名字即可
         print(x)
         x=1
         print(x)
         from another import x
         print(x)
        
         使用from...import的时候要注意,会和当前模块中的名字冲突。
         加载的顺序,按照调用顺序的先后
         from another import x,y
         y()
        
         使用from ..import也可以一次性将被导入模块的所有名字都导入
         慎用,因为被导入所有的名字可能会跟当前模块中的名字造成冲突。
         from another import *
         print(x)
         y()
        
         区别:
         使用import是一次性将模块下的所有名字都导入 ,使用的是要使用:模块名.名字
         from ..import,除了使用*以外,是一次导入模块下的一个名字,使用的时候,直接用名字
    
    3. 模块别名
         当导入模块时,可以使用as为模块进行重新指定名字
         语法:
        """
        import 模块1 as 别名1,模块2 as 别名2....
        from 模块 import 名字1 as 别名1  ,名字2 as 别名2....
         注意:有了别名,原名字不可用
        """
         import another as a1
         print(a1.x)
        
         from another import x as x1
         print(x1)
        
        """
        别名的好处:
        (1)使用别名可以解决当前模块名字跟导入模块名字冲突的问题
        (2)当名字特别长的时候,可以起到简化的作用
        """
    
    
    4.隐藏模块数据
         注意:只对from...import * 导入起作用
         两种方式
        (1)指定不能被导入的名字
         方式:在名字前面_,这样名字就不会被导入到其他模块中
         from another import *
         print(x)
         print(_w)
        
        (2)指定要被导入的名字
         __all__ 列表,列表中是希望被导入的名字,
         一定要指定的是名字,是要""括起来,否则导入的是对象
         from another import *
         print(x)
          print(z)
         print(_w)
        
         当一个_起名的变量,会放到__all__中,最终结果是可以被导入的
         原因是先加载__all__,然后才去加载其他不需要导入的变量。
    
    
    5.__name__
    
         在类中,指类的名字
        
         需求:因为在当前模块中导入其他模块,不一定其他模块的所有代码都希望在当前模块中执行。
         import another
        
         执行another,__name__
         (1)右键执行another,显示模块名  __main__
         (2)通过执行day12模块,导入another,间接执行another  显示模块名:another
        
         阻止一部分代码不在导入的模块中执行,可以使用__name__
         在被导入模块中加if __name__ =="__main__":,可以让当前模块被导入的时候,不执行if中的代码
         习惯上被当做主程序的调用
         函数定义、class定义
         def a():
             pass
        
         if __name__ =="__main__":
             a()
             
    6.模块的搜索路径
    
         import random
         print(random.randint(1,4))
         模块加载的顺序
        """
        1. 内建模块中加载
        2. 当前脚本所在路径中加载
        3. python的环境变量path加载
        4. python的安装路径 如:lib
        """
         注意:不要使用跟lib库同名的模块名
    
     7.模块的缓存
     
         导入模块的时候,被导入的模块代码除了 if __name__=="__main__"下的内容都会被执行加载一次
         每次导入时,被导入模块都被写入缓存
         当再次调用import或者from..import的时候,会直接加载缓存文件
         写入缓存:加快的模块的加载速度,但是并不能提高模块的执行速度
         当导入模块的时候,会创建缓存文件,缓存文件是二进制文件
         缓存文件可以脱离源文件执行。
    

    二、包
    “”"
    包是为了提供模块的分类管理
    包有独立的命名空间,可以解决模块名的冲突
    “”"
    1. 导入包

         语法跟模块基本类似
         import 包名 as 别名
         from 包名 import 模块名 as 别名
         import day12.another
         from day12.another import x
         print(x)
    
     2. __init__.py
     
         每个python的开发包都会具有一个__init__.py
         用来对于整个包进行初始化
         当加载包的时候,会执行这个包下的init文件
         import day12
         from day12 import another
         print(day12.x)
    
     3.__all__变量
     
         只针对from day12 import *有效,对import,from day12 import y
        from day12 import y
         from day12 import *
         __all__ 是一个列表,指定能够导入的名字
        print(y)
         print(x)
        
        
     普通的文件夹跟包的区别:
     普通的文件夹没有__init__.py,其他模块无法导入这个包中的文件。
     包下有__init__.py,其他模块可以导入包中的文件
    

    三、具体模块

    (一)math模块 数学模块
    
        import math
        圆周率
        print(math.pi)
        
         数学常数
        print(math.e)
        
         向上取整
        print(math.ceil(3.5))
        print(math.ceil(-3.5))
        
         向下取整
        print(math.floor(3.5))
        print(math.floor(-3.5))
        
         返回常数e的x的幂
        print(math.exp(1))
        
         x的y次幂
        print(math.pow(2,5))
        
         log ,默认以e为底
        print(math.log(8,2))
        
         浮点数的绝对值
        print(math.fabs(-3.5))
        
         取余
         正数:商向下取整
         负数:商向上取整
        print(math.fmod(10,-3))
        
        
         累加和
        print(math.fsum([1,2,3,4]))
        
        最大公约数
        print(math.gcd(12,15))
        
         返回x的平方根
        print(math.sqrt(9))
         print(math.sqrt(-9))
        
        
    (二)随机模块
    
        import random
        (1) 产生一个随机数,小数    0<=x<1
            print(random.random())
             while random!=0:
                 pass
             print()
        
        (2)randint(a,b)  a<=x<=b
            print(random.randint(1,3))
            
        (3)randrange(start,end,step)
             参数的意义跟range类似,相当于从range函数得到的结果中随机选一个
             包含起点,不包含终点
            print(random.randrange(1,3))
        
         (4)uniform(a,b)   返回a.b之间的浮点数,a<=x<=b
            print(random.uniform(1,2))
            
        (5) choice(seq) 从seq中随机选择一个元素
            print(random.choice([1,2,3,4,5]))
        
         (6)choices()从序列中随机选择n的元素,还可以设置权重
            print(random.choices([1,2,3,4,5],k=3,weights=[1,1,1,1,100]))
            随机选择一个数后,还会放回到样本中。
        
        (7)samle()随机选择n个数后,不会放回到样本中。
            print(random.sample([1,2,3],2))
        
        (8)shuffle()  就地洗牌
            li=[1,2,3,4,5,6]
            random.shuffle(li)
            print(li)
    
    
    
    (三)时间和日期模块
        时间:时间
        日期:年月日
    
        time  datetime
        
        1. time包 时间包
        
             提供了跟时间相关的操作
            import time
            
             (1)time.timezone 返回与UTC相差的秒数
                 UTC:世界标准时间:本初子午线上的时间
                 北京时间:东八区的时间
                print(time.timezone)
                
             (2)time() 从新纪元到当前时间走过的秒数
                 新纪元:unix产生时间 1970年1月1
                print(time.time())
            
             (3)localtime([seconds])
                 返回从新纪元走过seconds之后的时间。
                 如果参数不写,默认返回的是本地当前时间
                 返回一个时间元组
                print(time.localtime())
                print(time.localtime(1))
            
             (4)gmtime,返回与localtime([seconds])类似 ,返回的是utc时间
                 print(time.gmtime())
    
             (5)mktime:将时间元组转换成从新纪元到元组指定时间走过的秒数
                t=time.localtime()
                print(time.mktime(t))
                
             (6)time.ctime() 将从新纪元走过的毫秒数转换成本地时间,str
                print(time.ctime())
            
             (7)sleep:将程序暂停的时间
                 print("暂停之前")
                 time.sleep(1)
                 print("暂停之后")
    
             (8)clock 时钟,unix和window下作用不同。
                 winows下,
                 第一次调用:cpu的计算时间
                 第二次调用返回的距离第一次调用该函数所经历的时间
                 print(time.clock())
                 time.sleep(1)
                 print(time.clock())
                 time.sleep(1)
                 print(time.clock())
                
             (9)per_counter(),返回精准的性能计数器
                 包含了sleep函数的时间
                 start=time.perf_counter()
                 time.sleep(1)
                 end=time.perf_counter()
                 time.sleep(1)
                 end2=time.perf_counter()
                 print(end2-start)
                 print(end-start)
            
             (10)process_time,返回当前进程下,系统cpu计算时间,时间不包含sleep
                 start=time.process_time()
                 time.sleep(1)
                 end=time.process_time()
                 print(end-start)
            
             (11) 将时间元组转换成字符串
                 按照时间的模板转换,格式化
                t=time.localtime()
                print(time.strftime("%Y-%m-%d %H:%M:%S",t))
            
             (12)将字符串转换成时间元组
                 time.strptime(string,指定的格式):按照指定的格式解析字符串,形成时间元组
                 print(time.strptime("2018-10-10 02:05:06","%Y-%m-%d %H:%M:%S"))
                 print(time.strptime("2018/10-10 02:05:06","%Y-%m-%d %H:%M:%S"))
            
        2. datetime 日期包,年月日包
        
             date 处理日期
             time 处理时间
             datetime  处理日期和时间
            
            - date类,日期类型的对象
                
                (1)构造器  __init__方法,需要参数年月日
                    from datetime import date
                     date(year,month,day)
                    print(date(2018,10,24))
                     <date  内存地址>
        
                (2) 实例属性
                    d=date(2018,10,24)
                    print(d.year)
                    print(d.month)
                    print(d.day)
    
                (3)类属性
                    print(date.max)  9999-12-31
                    print(date.min)
                    print(date.resolution) 两个date类型的对象的间隔
    
                (4) 实例方法
                    d=date(2018,10,24)
                     ctime:返回特定格式的字符串来表示日期对象,返回值是字符串
                    print(d.ctime())
                    
                     replace,返回新的date对象,按照repalce的参数
                     不是就地改变,是新创建时间对象进行替换
                    print(d.replace(year=2017))
                    print(d)
                    
                     timetuple() 返回时间元组的对象,将当前的date类型的对象转换成时间元组
                    print(d.timetuple())
                    
                     weekday():返回当前date类型日期的星期几(0-6)
                    print(d.weekday())
                    
                     toordinal():返回当前date类型日期的时间序数
                     0001-01-01----1
                    print(d.toordinal())
                    
                     d.strftime()  时间对象转换成字符串。
                    strd=d.strftime("%Y/%m/%d")
                    print(type(strd))
                     print(d.strftime("%Y/%m/%d"))
                    print(type(d))
    
                 (5)类方法
                     date.today()返回当前日期的日期对象
                    s=date.today()
                    print(date.today(),type(s))
                    
                    根据传过来的时间序数,创建日期类型的对象
                     date.fromordinal(orinal)
                    print(date.fromordinal(1))
                    
                    根据传过来的参数(时间戳 秒)创建创建时间对象
                    print(date.fromtimestamp(3600*24+1))
    
            - time类
                 处理时间
                 
                (1)构造器  __init__
                    from datetime import time
                    print(time(3,4,5))
                     也可以传入微秒,有默认值
                    
                (2)实例属性
                    t=time(3,4,5)
                    print(t.hour)
                    print(t.minute)
                    print(t.second)
                    print(t.microsecond)
                
                (3)类属性
                    print(time.min)
                    print(time.max)
                    print(time.resolution)
                
                (4)实例方法
                    t=time(3,4,5)
                     t.replace()将时间对象中的hour  minute second micorsecond 替换成参数的值
                     新创建time类型的对象
                    print(t.replace(minute=6))
                    print(t)
                    
                     t.strftime()将时间类型的对象转换成字符串
                    print(t.strftime("%H*%M*%S"))
    
    
    
            - datetime类
            
                from datetime import datetime
                
                (1) 构造器 __init__
                    dt=datetime(2018,10,24,16,4,55)
                    print(dt,type(dt))
                
                 (2)实例属性
                    print(dt.year)
                    print(dt.month)
                    print(dt.day)
                    print(dt.hour)
                    print(dt.minute)
                    print(dt.second)
                    print(dt.microsecond)
                
                 (3)实例方法
                    dt.ctime()   返回datetime对象的指定格式的时间,字符串
                    print(dt.ctime())
                    
                     date()  返回date对象
                    d=dt.date()
                    print(d,type(d))
                    
                     time()  返回time对象
                    t=dt.time()
                    print(t,type(t))
                    
                     将datetime类型的对象属性进行替换,形成新的datetime类型对象
                    print(dt.replace(year=2017))
                    
                     dt.timetuple() 将datetime类型的对象转换成时间元组
                    print(dt.timetuple())
                
                     weekday
                    print(dt.weekday())
                    
                     strftime
                    print(dt.strftime("%Y/%m/%d %H:%M:%S"))
    
                 (4) 类属性
                    print(datetime.min)
                    print(datetime.max)
                    print(datetime.resolution)
                
                 (5)类方法
                    返回当前日期的年月日,时分秒
                    print(datetime.today())
                    print(datetime.now())
                    
                     utc
                    print(datetime.utcnow())
                    
                     datetime.fromordinal(o) 根据序数参数,转换成datetime类型的对象
                    print(datetime.fromordinal(1))
                    
                     datetime.fromtimestamp() 根据时间戳,转换层datetime类型的对象
                    print(datetime.fromtimestamp(3600*24+1))
                    
                    print(datetime.strptime("2018-10-24 16:17:55","%Y-%m-%d %H:%M:%S"))
                    
                    
                    import calendar
                    cal=calendar.month(2018,10)
                    print(cal)
    

    “”"

    展开全文
  • Python——模块(Module)和包(Package)

    万次阅读 多人点赞 2018-02-01 16:01:16
    1. 模块(Module) 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含...

    本文绝大部分内容转载至:廖雪峰官方网站

    1. 模块(Module)

    在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。

    为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)

    使用模块有什么好处?

    最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块

    使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突

    你也许还想到,如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)

    举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。

    现在,假设我们的abcxyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:

    mycompany
    ├─ __init__.py
    ├─ abc.py
    └─ xyz.py

    引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz

    请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。

    类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:

    mycompany
     ├─ web
     │  ├─ __init__.py
     │  ├─ utils.py
     │  └─ www.py
     ├─ __init__.py
     ├─ abc.py
     └─ xyz.py

    文件www.py的模块名就是mycompany.web.www

    Notes: 自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。

    2. 使用模块

    Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。

    我们以内建的sys模块为例,编写一个hello的模块:

    #!/usr/bin/env python3 
    # -*- coding: utf-8 -*-
    
    ' a test module '
    
    __author__ = 'Michael Liao'
    
    import sys
    
    def test():
        args = sys.argv   # argv参数用列表存储命令行的所有参数
        if len(args)==1:  # 当列表长度为1时即只有一个参数时
            print('Hello, world!')
        elif len(args)==2: # 当命令行有两个参数时
            print('Hello, %s!' % args[1])
        else:
            print('Too many arguments!')
    
    if __name__=='__main__':
        test()

    第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;

    第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

    第6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;

    以上就是Python模块的标准文件模板,当然也可以全部删掉不写,但是,按标准办事肯定没错。

    后面开始就是真正的代码部分。

    你可能注意到了,使用sys模块的第一步,就是导入该模块:

    import sys

    导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。

    sys模块有一个argv变量,list存储了命令行的所有参数argv至少有一个元素,因为第一个参数永远是该.py文件的名称,例如:

    运行python3 hello.py获得的sys.argv就是['hello.py'],注意这里python3不算是参数;

    运行python3 hello.py Michael获得的sys.argv就是['hello.py', 'Michael]

    最后,注意到这两行代码:

    if __name__=='__main__':
        test()

    当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试

    我们可以用命令行运行hello.py看看效果:

    $ python3 hello.py
    Hello, world!
    $ python hello.py Michael
    Hello, Michael!

    如果启动Python交互环境,再导入hello模块:

    >>> import hello
    >>>

    导入时,没有打印Hello, word!,因为没有执行test()函数。

    调用hello.test()时,才能打印出Hello, word!

    >>> hello.test()
    Hello, world!
    展开全文
  • Python中的导入模块

    万次阅读 2018-06-02 09:51:56
    1,导入模块的的几种方式 模块是什么? 模块实际上就是 以.py为结尾的文件 注意点:自定义的模块尽量不要和系统模块重名 模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入,导入模块简单划分,...

    1,导入模块的的几种方式

    模块是什么?
    模块实际上就是 以.py为结尾的文件
    注意点:自定义的模块尽量不要和系统模块重名

    模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入,导入模块简单划分,实际上就只有两种:

    • import ……
    • from …… import

    详细一点划分有五种:

    • 1,improt 模块名
      调用:模块名.功能名
    • 2,import 模块名 as 别名
      调用:别名.功能名
    • 3,from 模块名 import 功能名
      调用:直接功能名
    • 4,from 模块名 import 功能名 as 别名
      调用: 直接拿别名来用
    • 5,from 模块名 import * (用 * 号 一次性导入所有功能)
      调用:直接功能名
      注意点:* 号没法用别名

    2,模块的搜索路径

    sys.path 返回导入模块时的搜索路径集,是一个list列表。

    这里写图片描述

    • 从上面列出的目录里依次查找要导入的模块文件
    • ’ ’ 表示当前路径
    • 列表中的路径的先后顺序代表了python解释器在搜索模块时的先后顺序

    可以添加新的模块:

    • sys.path.append(‘/home/python/xxx’)
    • sys.path.insert(0, ‘/home/python/xxx’) # 可以确保先搜索这个路径
    • 注意点:sys.path.append(path)和sys.path.insert(path)添加的相关路径,在退出交互式环境或者IDE后会自动消失。
    In [37]: sys.path.insert(0,"/home/python/xxxx")
    In [38]: sys.path
    Out[38]:
    ['/home/python/xxxx',
     '',
     '/usr/bin',
     '/usr/lib/python35.zip',
     '/usr/lib/python3.5',
     '/usr/lib/python3.5/plat-x86_64-linux-gnu',
     '/usr/lib/python3.5/lib-dynload',
     '/usr/local/lib/python3.5/dist-packages',
     '/usr/lib/python3/dist-packages',
     '/usr/lib/python3/dist-packages/IPython/extensions',
     '/home/python/.ipython']

    3,重新导入模块

    模块被导入后,import module不能重新导入模块,重新导入需用reload

    创建一个reload_test.py文件,里面写一个test方法

    这里写图片描述

    打开 ipython 终端导入 reload_test 模块

    这里写图片描述

    修改reload_test.py 文件中的test方法

    这里写图片描述

    再一次import reload_test 模块 然后调用test方法会发现值没变
    这里写图片描述

    原因:import 导入模块只会导入一次,因此即使模块被修改了,import也不会重新导入
    解决方案

    1. 关闭终端,重新打开,然后再import 导入一次
    2. 用 reload 可以在不关闭终端的情况下重新导入

    这里写图片描述

    4,多模块开发时,要注意修改导入模块的值时,from……import 与 import 导入模块的区别

    main.py

    from send import *
    from show import *
    
    # 主流程
    def main():
        # 发女朋友
        send()
        # 秀恩爱
        show()
    
    
    if __name__ == '__main__':
        main()

    send.py

    #import girl
    from girl import *
    
    # 发女朋友
    def send():
        print("发女朋友了,翠花是你的了")
        #girl.have_girl = True
        have_girl = True

    show.py

    # import girl
    from girl import *
    
    # 秀恩爱
    def show():
        if have_girl == True:
        #if girl.have_girl == True:
            print("我有女朋友了,好开心")
        else:
            print("单身贵族")

    girl.py

    # 共同变量模块
    
    have_girl = False #False代表没有女朋友 True代表有女朋友

    运行结果:

    发女朋友了,翠花是你的了
    单身贵族
    

    是不是有点惊讶?结果难道,不应该是这样的吗:

    发女朋友了,翠花是你的了
    我有女朋友了,好开心
    

    会产生这种情况的原因:
    import girl 可以理解为地址的复制,也就是 引用 用来修改值
    from girl import * 可以理解成内容的复制,也就是深拷贝,那么深拷贝有什么特点,深拷贝最大的特点就是数据独立。
    这里写图片描述

    展开全文
  • 组件、插件、模块、子应用、库、框架等概念辨析 网上有许多讲组件化、模块化等概念的文章,但大家一般都是将这两个概念混为一谈的,并没有加以区分。而且实际上许多人对于组件、插件、模块、子应用等概念的区别也不...
  • Python中包、库与模块的区别

    万次阅读 2018-06-24 16:31:49
    python中模块,包,库的概念... 包:在模块之上的概念,为了方便管理而将文件进行打包。包目录下第一个文件便是 __init__.py,然后是一些模块文件和子目录,假如子目录中也有 __init__.py,那么它就是这个包的子包...
  • python12:模块

    千次阅读 2015-04-27 10:50:10
    到目前为止,你已经可以使用python实现你想要的功能。但当你编码一段时间后,随着代码量的增长,你可能想将你的代码分解为多个...在一个模块中的定义能被导入其它模块或者主模块中。 模块基础 一个模块就是一个文件
  • 模块化开发简述

    千次阅读 2018-08-14 11:52:43
    模块化开发简述 都说模块化开发为前端发展带来了巨大的进步,然而不熟悉的人看着也是两眼一懵,那其实这到底是什么?好处在哪?我来说说自己的见解吧。 1. 模块化和传统开发的区别 实话讲,其实在我看来,...
  • python 日志 logging模块(详细解析)

    万次阅读 多人点赞 2019-05-31 09:51:08
    1 基本使用 转自:...配置logging基本的设置,然后在控制台输出日志, import logging logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(...
  • Python 基础(十):模块与包

    千次阅读 2019-12-13 08:40:51
    模块与包的定义和使用
  • python glob模块

    万次阅读 多人点赞 2012-04-17 15:45:59
    glob模块是最简单的模块之一,内容非常少。用它可以查找符合特定规则的文件路径名。跟使用windows下的文件搜索差不多。查找文件只用到三个匹配符:"*", "?", "[]"。"*"匹配0个或多个字符;"?"匹配单个字符;"[]"匹配...
  • Python 库、包、模块

    千次阅读 2018-09-23 16:23:42
    文章目录库库定义标准库第三方库python第三方库如何寻找自定义库包包的概念**python 中`_init_.py`文件的作用模块模块定义导入模块import 语句from-import 语句问题:python 解释器如何查找要引入的模块python目录...
  • 什么是模块化,模块化的好处是

    千次阅读 2019-07-15 20:25:43
    什么是模块化,模块化的好处是? 模块化是一种处理复杂系统分解为更好的可管理模块的方式。 所谓的模块化开发就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是实现某一特定的功能。模块化开发的基础...
  • 驱动模块和桩模块的概念和区别

    万次阅读 多人点赞 2011-09-25 11:03:51
    模块和驱动模块(以C语言为例):  很多人对桩模块和驱动模块的概念会搞不清楚,那么下面来介绍这两个概念:  模块结构实例图:  假设现在项目组把任务分给了7个人,每个人负责实现一个模块。你负责的是B...
  • 使用子模块后,不必负责子模块的维护,只需要在必要的时候同步更新子模块即可。 本文主要讲解子模块相关的基础命令,详细使用请参考man page。 子模块的添加 添加子模块非常简单,命令如下: git ...
  • MATLAB Simulink模块库详解(一)Sources篇

    万次阅读 多人点赞 2018-07-16 09:41:56
    MATLAB Simulink模块库详解(一)Sources篇Simulink模块库概述1.Sources模块库,为仿真提供各种信号源2.Sinks模块库,为仿真提供输出设备元件3.Continuous模块库,为仿真提供连续系统4.Discrete模块库,为仿真提供...
  • 什么是测试桩和驱动?
  • L298N电机驱动模块详解

    万次阅读 多人点赞 2018-06-24 20:29:05
  • 从目录中导入已存在的项目;从版本控制系统中检出项目;...idea的project的模块都是配置在project_dir/.idea/modules.xml中的,新建的项目本身默认是这个项目的第一个模块模块本身是没有层级的。在项目
  • 4.0低功耗蓝牙解决方案

    万次阅读 2012-08-22 14:09:04
    4.0低功耗蓝牙解决方案 蓝牙汽车DVD模块 蓝牙车载免提模块 蓝牙音箱模块 蓝牙数据传送模块 蓝牙音频模块 蓝牙适配器模块 蓝牙音箱 电脑蓝牙模块 蓝牙个人数字助理模块 蓝牙PDA模块 蓝牙电脑配件模块 蓝牙无线接入
1 2 3 4 5 ... 20
收藏数 2,625,041
精华内容 1,050,016
关键字:

模块