zoukankan      html  css  js  c++  java
  • python 模块管理

    要点概论:

    1.引言

    2. 用模块建立抽象层

    3. 管理模块名称

    4. 设置 PTH 文件(待补充)

    5.附录

    1. 引言

      python是个支持多范式的程序设计语言,无论采取过程式,函数式或面向对象,在构建程序时都应该思考以下几个重点。

      1)抽象层的封装与隔离

      2)对象的状态

      3)命名空间

      4)资源实体的组织方式,像源码文件,软件包等

      在python中,模块也提供了一种抽象层的封装与隔离,下面来了解以下如何善用模块建立最自然的抽象层

    2.用模块建立抽象层

      一个 .py 文件就是一个模块,这使得模块称为python中最自然的抽象层。想要直到一个模块中有哪些名称,可以使用 dir() 函数。

      实际上,当 import 某个模块而使得指定的 .py 文件被加载时,python 解释器会为它创建一个 module 实例,并创建一个模块名称来引用它,

      dir() 实际上时查询模块名称引用的 module 实例上有哪些属性(Attribute)名称可以存取。

      PS:若调用 dir() 时未指定任何 module 实例,则会插叙当前所在模块的 module 实例上拥有的名称。

      下面我们来设计一个银行业务相关的简单程序,并把它定义在一个 bank.py 文件中:

    # bank.py
    
    def account(name,number,balance):
        return {'name':name,'number':number,'balance':balance}
    
    def deposit(acct,amount):
        if amount <= 0:
            print('存款金额不能为负')
        else:
            acct['balance'] += amount
    
    def withdraw(acct,amount):
        if amount > acct['balance']:
            print('金额不足')
        else:
            acct['balance'] -= amount
    
    def desc(acct):
        return 'Account:' + str(acct)
    bank.py

    接下来再其他的 py 文件中 import bank:

    import bank
    
    acct = bank.account('zhaoyi','123-4567',1000)
    bank.deposit(acct,500)
    bank.withdraw(acct,200)
    
    print(bank.desc(acct))
    
    # Account:{'number': '123-4567', 'name': 'zhaoyi', 'balance': 1300}
    import bank

      bank 这个名称不单只是用来避免命名空间的冲突,也时作为一种组织与思考相关功能的方式。

    3. 管理模块名称

      大部分情况下模块都会被拿来作为命名空间。下面介绍一些引用模块的方式:

      1) from import 名称管理

         from import 变将被导入模块中名称引用的值赋给当前模块中创建的新名称,

    例如,在 foo.py 中定义了一个 x 变量:

    x = 10
    foo.py

    在另一个 main.py 文件中执行 from foo import x ,实际上会在 main 模块中创建一个 x 变量然后将 foo 中 x 的值 10 赋值给 main 中的 x 变量:

    from foo import x
    
    print(x)     # 10
    
    x = 20
    
    print(x)    #20
    
    import foo
    
    print(foo.x)    #10
    main.py

    简单来说,当执行 from foo import x 时,就是在模块中创建了新变量,而不是使用原本的 foo.x 变量,只是一开始两个变量引用同一个值。

    但是,若引用了可变动对象,就要特别小心了。

    例如,在foo.py中定义一个 l1 = [10,20]:

    l1 = [10,20]
    foo.py
    from foo import l1
    
    print(l1)       #[10, 20]
    l1[0] = 15
    print(l1)       #[15, 20]
    
    import foo
    print(foo.l1)   #[15, 20]
    main.py

    这是因为 l1 变量与 foo.l1 都引用了同一个列表(list)对象,因此通过 l1 变量修改索引 0 的元素使用 foo.l1 就会获取修改后的结果。

      

      2)限制 from import *

        在当前模块中,如果有些变量不想被 from import *创建同名变量(避免命名空间混乱),有两种方法,

    第一种方法用下划线作为开头,例如:

    x = 10
    l1 = [10,20]
    _y = 20
    foo.py
    from foo import *
    
    print(x)    #10
    print(l1)   #[10,20]
    print(_y)   # NameError: name '_y' is not defined
    main.py

    另一种方法是定义一个 __all__ 列表,使用字符串列处可被 from import * 的名称,例如:

    __all__ = ['x','l1']
    x = 10
    l1 = [10,20]
    _y = 20
    z = 30
    foo.py
    from foo import *
    
    print(x)    #10
    print(l1)   #[10,20]
    print(z)   # NameError: name 'z' is not defined
    main

    需要注意的是:无论是下划线开头,还是未被列入 __all__ 列表的名称,只是限制不被 from import *,如果用户 import foo,那么依旧可以使用 foo.x 或 foo._y来存取。

    import foo
    
    print(foo.x)    # 10
    print(foo._y)   # 20
    main.py

      3)del 模块名称

        del 可以将已创建的变量删除。

        被 import 的模块名称或者 from import 创建的名称实际上就是个变量,因此可以使用 del 将模块名称或者 from import 的名称删除。

    例如:

    import foo
    print(foo.x)    # 10
    del foo
    print(foo.x)    # name 'foo' is not defined
    
    from foo import x
    print(x)        # 10
    del x
    print(x)        # name 'x' is not defined
    main.py

    如果想模拟 import foo as qoo,那么可以如下方法实现:

    import foo
    qoo = foo
    del foo
    print(qoo.x)    # 10
    print(foo.x)    # name 'foo' is not defined
    main.py

      4)sys.modules

        del 用来删除指定的名称而不是删除名称引用的对象本身。

    举例来说:

    l1 = [1,2]
    l2 = l1
    
    del l1
    
    print(l2)   # [1, 2]
    print(l1)   # name 'l1' is not defined
    main.py

       在上例中,虽然执行了 del l1,然而 l2还是引用着列表实例。

       也就是说,del 只是将该名称删除,而不是删除 module 实例。

    想要知道当前已加载的 module 名称与实例有哪些,可以通过 sys.modules 【这是个字典对象,键的部分是模块名称,值的部分是 module 实例】,例如:

    import sys
    import foo
    
    print('foo' in sys.modules) # True
    print(foo.x)                 # 10
    del foo
    print(foo.x)                 # name 'foo' is not defined
    print(sys.modules['foo'])   # 10
    main.py

      上面的例子可以看到, del foo 删除了 foo名称,然而,我们还是可以通过 sys,module['foo'] 存取到 foo 原来引用的 module 实例。

      5)模块名称的作用域

        实际上引用模块可以出现在语句能出现的位置,例如 if...else区块或者函数之中,因此能根据不同的情况进行不同的 import。

    当使用 import,import as,from import 时,创建的名称其实就是变量名称,因此根据使用 import,import as,from import 的位置所创建的名称也会有其作用域。例如:

    def foo():
        import foo
        print(foo.x)
    
    foo()           # 10
    print(foo.x)    # AttributeError: 'function' object has no attribute 'x'
    main.py

      

     4. 设置 PTH 文件(待补充)

    5. 附录

      一个模块被 import 时发生的事情:

      1) 在 sys.path 寻找模块

      2) 加载,编译模块的程序代码

      3) 创建空的模块对象

      4) 在 sys,modules 中记录该模块

      5) 执行模块中的程序代码及相关定义

       

      

      

  • 相关阅读:
    Android酷炫实用的开源框架(UI框架)
    The official raywenderlich.com Objective-C style guide.
    mac os 利用ssh 搭建git server服务器详细教程,以及git基本用法
    创建者模式
    工厂模式之我见
    设计模式的学习
    MSSQL基础
    Ini文件帮助类
    Nuget的使用
    Oracle批量执行脚本文件
  • 原文地址:https://www.cnblogs.com/HZY258/p/8456366.html
Copyright © 2011-2022 走看看