今日主要内容

一、包

(一)什么是包

  • 只要是含有__init__.py文件的文件夹就是一个包
  • 包的本质其实就是一个文件夹,利用包将不同功能的模块组织起来,以此来提高程序的结构性和可维护性
  • 包是用来导入的,不是用来执行的,所以它和软件开发规范分文件管理还是有区别的,一个是项目,一个是用来导入的包
  • 正因为包是用来导入的,所以运行文件一定要放在包的外面

(二)创建一个包

  • 利用代码创建一个包

    import os
    os.makedirs('glance/api')
    os.makedirs('glance/cmd')
    os.makedirs('glance/db')
    l = []
    l.append(open('glance/__init__.py','w'))
    l.append(open('glance/test.py','w'))
    l.append(open('glance/api/__init__.py','w'))
    l.append(open('glance/api/policy.py','w'))
    l.append(open('glance/api/versions.py','w'))
    l.append(open('glance/cmd/__init__.py','w'))
    l.append(open('glance/cmd/manage.py','w'))
    l.append(open('glance/db/models.py','w'))
    map(lambda f:f.close() ,l)
    • 下述所有内容,均以此图结构为基础

(三)__init__.py文件

  • 在我们导入包的时候,其实本质上导入的就是__init__.py文件,解释器会自动执行__init__.py文件中的内容

    # glance/__init__.py
    print("这里是glance下的__init__.py文件") # run.py
    import glance 运行结果:
    这里是glance下的__init__.py文件

(四)包的导入

  • 包的导入,须注意两点内容:

    • 导入时无论是使用import还是使用from xxx import xxx导入,点的前面必须是一个包
    • 使用from xxx import xxx导入时,import前可以出现点,import后不能出现点
  1. 常规导入

    • import导入
    # policy.py
    def policy_func():
    print("这是policy文件中的函数") # run.py
    import glance.api.policy glance.api.policy.policy_func() 运行结果:
    这是policy文件中的函数 # 成功导入
    • from import导入
    # policy.py
    def policy_func():
    print("这是policy文件中的函数") # run.py
    from glance.api.policy import policy_func policy_func() 运行结果:
    这是policy文件中的函数 # 成功导入
  2. 包内部之间的导入:

    • 包内部之间的相互引用,只能用绝对导入和相对导入,不能直接导入,比如policy.py文件需要导入versions.py文件中的函数,如果直接import导入会报找不到该模块的错误

      • 包内部互相引用的时候不能直接导入
      # versions.py
      def versions_func():
      print("这是versions文件中的函数") # policy.py
      import versions # 直接导入versions模块,在外面的run文件中运行,就无法找到versions模块 def policy_func():
      versions.versions_func()
      print("这是policy文件中的函数") # run.py
      from glance.api import policy policy.policy_func() 运行结果:
      ModuleNotFoundError: No module named 'versions'
      • 原因分析:如果直接在policy文件中运行程序,完全没有问题,因为此时policy文件的模块查找路径中包含versions模块,但是**包是用来导入的,如果在包外的run文件中导入policy模块,此时模块查找路径就变为了run文件所在的路径,所以当policy文件导入versions模块时,路径下并没有versions模块,所以找不到该模块
    • 绝对导入:

    # versions.py
    def versions_func():
    print("这是versions文件中的函数") # policy.py
    from glance.api import versions def policy_func():
    versions.versions_func()
    print("这是policy文件中的函数") # run.py
    from glance.api import policy policy.policy_func() 运行结果:
    这是versions文件中的函数
    这是policy文件中的函数
    • 相对导入:
    # versions.py
    def versions_func():
    print("这是versions文件中的函数") # policy.py
    from . import versions def policy_func():
    versions.versions_func()
    print("这是policy文件中的函数") # run.py
    from glance.api import policy policy.policy_func() 运行结果:
    这是versions文件中的函数
    这是policy文件中的函数
    • 只要使用了相对导入的模块,只能作为模块使用,不能作为脚本(终端中直接运行的文件成为脚本)使用,说白了就是不能直接运行
    # versions.py
    def versions_func():
    print("这是versions文件中的函数") # policy.py
    from . import versions def policy_func():
    versions.versions_func()
    print("这是policy文件中的函数") 运行结果:
    ImportError: cannot import name 'versions'
  3. 单独导入包,并使用包内的包或模块

    • 单独导入一个包,其本质上导入的只是__init__.py文件,包中其他的文件并没有被导入
    # policy.py
    def policy_func():
    print("这是policy文件中的函数") # run.py
    import glance # 只导入了__init__.py文件 glance.api.policy.policy_func() # 并不能使用 运行结果:
    AttributeError: module 'glance' has no attribute 'policy'
    • 此时就要利用到__init__.py文件了,__init__.py文件在包中起到了交接管理的作用,可以在__init__.py文件中导入每个子文件,也可以控制其是否能被导入,所以每一个包中必须要有__init__.py文件
    # policy.py
    def policy_func():
    print("这是policy文件中的函数") # glance/__init__.py
    from . import api # glance/api/__init__.py
    from . import policy # run.py
    import glance glance.api.policy.policy_func() 运行结果:
    这是policy文件中的函数
    • 直接调用模块中的方法
    # policy.py
    def policy_func():
    print("这是policy文件中的函数") # glance/__init__.py
    from .api import * # glance/api/__init__.py
    from .policy import * # run.py
    import glance glance.policy_func() 运行结果:
    这是policy文件中的函数
    • 还可以通过__all__来控制模块和模块中函数的导入

      • 控制模块导入
      # glance/__init__.py
      from .api import * # glance/api/__init__.py
      __all__ = ["versions"] # 只能导入versions,其余api下模块都不能被导入 # run.py
      import glance glance.policy 运行结果:
      AttributeError: module 'glance' has no attribute 'policy'
      • 控制方法导入
      # policy.py
      def policy_func():
      print("这是policy文件中的func") def policy_foo():
      print("这是policy文件中的foo") # glance/__init__.py
      from .api import * # glance/api/__init__.py
      from .policy import *
      __all__ = ["policy_foo"] # 控制只能导入foo函数,其余函数都不能被导入 # run.py
      import glance glance.policy_func() 运行结果:
      AttributeError: module 'glance' has no attribute 'policy_func'

Python基础(十八)的更多相关文章

  1. Bootstrap <基础十八>面包屑导航(Breadcrumbs)

    面包屑导航(Breadcrumbs)是一种基于网站层次信息的显示方式.以博客为例,面包屑导航可以显示发布日期.类别或标签.它们表示当前页面在导航层次结构内的位置. Bootstrap 中的面包屑导航( ...

  2. python 基础(十) 面向对象

    面向对象 一.概念 类(class): 用来描述具有相同属性和方法的对象的集合 对象是类的实例化 类变量:类变量在整个实例化的对象中是共用的.定义在类中 并且是函数体外的 实例变量:只能作用于 当前类 ...

  3. python基础(八种数据类型)

    Python的八种数据类型 八种数据类型分别是: number(数字).string(字符串).Boolean(布尔值).None(空值) list(列表).tuple(元组).dict(字典).se ...

  4. python基础-第八篇-8.1初识Socket

    socket基础 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. so ...

  5. Python基础(八)装饰器

    今天我们来介绍一下可以提升python代码逼格的东西——装饰器.在学习装饰器之前我们先来复习一下函数的几个小点,方便更好的理解装饰器的含义. 一.知识点复习 1, 在函数中f1和f1()有什么不同,f ...

  6. python基础知识八

    当你的程序中出现某些 异常的 状况的时候,异常就发生了.例如,当你想要读某个文件的时候,而那个文件不存在.或者在程序运行的时候,你不小心把它删除了.上述这些情况可以使用异常来处理. 如你的程序中有一些 ...

  7. python基础(八)-迭代器与生成器

    一.迭代器 li=[1,2,3] f=li.__iter__() print(f) print(f.__next__()) print(f.__next__()) print(f.__next__() ...

  8. Python爬虫(十八)_多线程糗事百科案例

    多线程糗事百科案例 案例要求参考上一个糗事百科单进程案例:http://www.cnblogs.com/miqi1992/p/8081929.html Queue(队列对象) Queue是python ...

  9. Python基础篇(八)

    key words:私有变量,类静态变量,生成器,导入Python模块,r查看模块可以使用的函数,查看帮助信息,启动外部程序,集合,堆,时间模块,random模块,shelve模块,文件读取等 > ...

  10. 小甲鱼Python第十八讲课后习题

    笔记: 1.函数与过程:过程(procedure)是简单的,特殊且没有返回值的:函数(Function)有返回值 Python严格来说只有函数没有过程 2.局部变量:在局部生效如在函数中定义的变量 3 ...

随机推荐

  1. 用户数从 0 到亿,我的 K8s 踩坑血泪史

    作者 | 平名 阿里服务端开发技术专家 导读:容器服务 Kubernetes 是目前炙手可热的云原生基础设施,作者过去一年上线了一个用户数极速增长的应用:该应用一个月内日活用户从零至四千万,用户数从零 ...

  2. LeetCode 笔记

    Valid Sudoku 数独整体能够满足的情况是比较复杂.参考:编程之美 关于数独问题的讨论 这道题的解法可能简单一点,因为对输入进行来限制.只是去判断是否是一个数独数独的形式相比较来说也是较简单的 ...

  3. CF - 1130 E Wrong Answer

    PS:换了一种方式 希望大家喜欢 2333 /** code by: zstu wxk time: 2019/03/01 Problem Link: http://codeforces.com/con ...

  4. CodeForces Round 525

    A:Ehab and another construction problem #include<bits/stdc++.h> using namespace std; #define F ...

  5. 牛客网暑期ACM多校训练营(第二场) D money 思维

    链接:https://www.nowcoder.com/acm/contest/140/D来源:牛客网 White Cloud has built n stores numbered from 1 t ...

  6. Atcoder D - Black and White Tree(树dp+博弈)

    题目链接:http://agc014.contest.atcoder.jp/tasks/agc014_d 题意:有一棵树先手涂白色,后手涂黑色,直到不能再涂为止.涂完后再把所有黑色直接相邻的白色都变成 ...

  7. 【Offer】[57-2] 【和为S的连续正数序列】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数).例如,输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以 ...

  8. Cookie与Seesion的作用

    1.什么是Cookie与Session? cookie:首次访问服务器,服务器返回cookie置浏览器,存到用户电脑.之后去访问同一服务器,浏览器会携带相应cookie判断是否是同一浏览器的访问,告知 ...

  9. Git使用(一)安装配置过程-Win7

    公司项目需要使用Git作为项目的代码库管理工具.正好借此机会写个安装过程 1.首先下载Git下载地址:https://git-scm.com/download/win 当前下载版本:Git-2.13. ...

  10. ReentrantLock——可重入锁的实现原理

    一. 概述 本文首先介绍Lock接口.ReentrantLock的类层次结构以及锁功能模板类AbstractQueuedSynchronizer的简单原理,然后通过分析ReentrantLock的lo ...