Python基础(十八)

今日主要内容

一、包

(一)什么是包

  • 只要是含有__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'
      

原文地址:https://www.cnblogs.com/tianlangdada/p/11629672.html

时间: 2024-08-11 03:17:53

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

Python基础篇(八)

key words:私有变量,类静态变量,生成器,导入Python模块,r查看模块可以使用的函数,查看帮助信息,启动外部程序,集合,堆,时间模块,random模块,shelve模块,文件读取等 >>> class Rectangle: ...     def __init__(self): ...         self.__width = 0 ...         self.__height = 0 ...     def setSize(self,width,height): .

Python第十八课(面向对象基础)

Python第17课(面向对象基础)    >>>思维导图>>>中二青年 什么是继承? 继承是一种关系,描述两个对象之间,什么是什么的关系 例如麦兜,佩奇,猪刚鬣 都是猪啊, 在程序中,继承描述的是类和类之间的关系 例如a继承了b, a就能直接使用b已经存在的方法和属性 a称之为子类,b称之为父类,也称之为基类 为什么要使用继承 继承的一方可以直接使用被继承一方已经有的东西 其目的是为了重用已经有的代码,提高重用性 如何使用继承 语法 class 类名称(父类的名称):

Python基础(八)装饰器

今天我们来介绍一下可以提升python代码逼格的东西——装饰器.在学习装饰器之前我们先来复习一下函数的几个小点,方便更好的理解装饰器的含义. 一.知识点复习 1, 在函数中f1和f1()有什么不同,f1:表示的是将整个函数看作一个整体:f1():表示执行f1函数,下面通过一个例子来看一下: 1 2 3 4 5 def f1():     print('f1') f1                    #代表函数体本身,什么也不操作 f1()                  #代表执行函数

python基础(八种数据类型)

Python的八种数据类型 八种数据类型分别是: number(数字).string(字符串).Boolean(布尔值).None(空值) list(列表).tuple(元组).dict(字典).set(集合). 下面,我将这八种类型的相关知识,做一个梳理. 1.number(数字类型) 2.string(字符串类型) 3.Boolean(布尔值)与空值 4.list(列表类型) 5.tuple(元组类型) 6.dict(字典类型) 7.set(集合类型) 8.数据类型装换 原文地址:https

Python(十八)

一 什么是面向对象的程序设计及为什么要有它 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了程序的复杂度 缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身. 应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等. 面向对象的程序设计的核心是对

Python基础(十二) 类私有成员和保护成员

python中的protected和private python中用 _var :变量名前一个下划线来定义,此变量为保护成员protected,只有类及其子类可以访问.此变量不能通过from XXX import xxx 导入 __var;变量名前两个下划线来定义,此变量为私有private,只允许类本身访问,连子类都不可以访问. class perent_class(object): def __init__(self,name,protected,private): self.name =

Python基础(十) __init__与__new__区别

__init__与__new__区别: __init__在python,其实是,在实例化之后执行的,用来初始化一些属性,相当于构造函数,但是又不一样 细心一些,通过参数会有所发现,其实__init__(self)  self隐式的将,实例传过来. __new__在python中其实是,在实例化之前执行的,这个通过参数一样可以看出 __new__(cls),cls是隐式的传递的类对象,并不是实例.因为__new__的任务就是,创建类实例并返回实例. class temp(object): def

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

多线程糗事百科案例 案例要求参考上一个糗事百科单进程案例:http://www.cnblogs.com/miqi1992/p/8081929.html Queue(队列对象) Queue是python中的标准库,可以直接import Queue引用:队列时线程间最常用的交互数据的形式. python下多线程的思考 对于资源,加锁是个重要的环节.因为python原生的list,dict等,都是not thread safe的.而Queue,是线程安全的,因此在满足使用条件下,建议使用队列 初始化:

python基础(八):函数

函数就是将一些语句集合在一起的部件,他们能够不止一次的程序中运行,函数还能够计算出一个返回值,并能够改变作为函数输入的参数.而这些参数在代码运行时每次都不同.以函数的形式去编写一个操作可以使它成为一个广泛的应用工具. 基本格式: def 函数名: 函数体 return 返回值 定义和调用 定义函数按照前面的基本格式定义函数,调用函数时要使用函数名加括号来调用函数,括号中可以包含一个或多个参数.这些参数将会传递给函数头部的参数名. #定义 def test(x,y): return x*y #调用

python基础(八)

一.token加盐处理# import itsdangerous## salt='sdf234^#[email protected]'# t = itsdangerous.TimedJSONWebSignatureSerializer(salt,expires_in=30)# # res = t.dumps({'username':'yangfan','user_id':1})# # token = res.decode()# # print(token)# s='eyJhbGciOiJIUzI