• 025 包


    模块

    模块是什么?

    • 模块就是 Python 文件
    • 一个模块就是一个包含 Python 代码的文件
    • 后缀名成是 .py 就可以

    为什么用模块?

    • 程序太大,编写维护不方便,需要拆分
    • 模块可以增加代码重复利用的方式
    • 当做命名空间使用,避免命名冲突

    如何定义模块?

    • 模块就是一个普通文件,所以任何代码可以直接书写
    • 不过根据模块的规范,最好在模块中编写以下内容
      • 函数(单一功能)
      • 类(相似功能的组合,或者类似业务模块)
      • 测试代码

    如何使用模块?

    • 一般,模块可以直接导入
    • 若模块名称以数字开头,需要借助 importlib 帮助

    例1

    • 方便起见,在同一个文件夹内测试
    # student.py
    class Student(object):
        def __init__(self, name="NoName", age=18):
            self.name = name
            self.age = age
    
        def say(self):
            print("My name is {}.".format(self.name))
    
    
    def say_hello():
        print("Hi, this module's name is 'student'.")
    
    
    if __name__ == "__main__":
        print(">>> module Student")  # 避免模块代码被导入时自动执行
    
    • 导入自己的模块
    # test_student.py
    import student
    
    stu = student.Student("Tom")
    stu.say()
    print(stu.age)
    
    student.say_hello()
    

    例2

    # 01_student.py
    class Student(object):
        def __init__(self, name="NoName", age=18):
            self.name = name
            self.age = age
    
        def say(self):
            print("My name is {}.".format(self.name))
    
    • 使用 importlib 导入模块名以数字开头的模块
    # import 01_student  # SyntaxError: invalid token
    import importlib
    
    new = importlib.import_module("01_student")  # 可以理解成 import 01_student as new
    stu = new.Student()
    stu.say()
    

    例3

    • 导入模块的同时起一个别名
    import student as st
    
    stu = st.Student("Jerry", 17)
    stu.say()
    print(stu.age)
    
    st.say_hello()
    

    例4

    • 使用时不需要前缀
    from student import Student, say_hello
    
    stu = Student("Tom")
    stu.say()
    print(stu.age)
    
    say_hello()
    

    例5

    • 导入模块的所有内容
    from student import *
    
    stu = Student("Tom")
    stu.say()
    print(stu.age)
    
    say_hello()
    

    模块的搜索路径

    什么是模块的搜索路径?

    • 加载模块的时候,系统会在模块的搜索路径寻找目标模块
    import sys
    
    # sys.path 属性可以获取路径列表
    print(type(sys.path))
    print(sys.path)
    
    for p in sys.path:
        print(p)
    

    如何添加搜索路径?

    • sys.path.append(dir)

    模块按什么顺序加载?

    1. 搜索内存中已经加载好的模块
    2. 搜索 Python 的内置模块
    3. 搜索 sys.path 路径

    • 包是一种组织管理代码的方式
    • 包里面存放的是模块
    • 用于将模块包含在一起的文件夹就是包

    自定义包的结构是怎样的?

    |---包
        |--- __init__.py  包的标志文件
        |--- 模块1
        |--- 模块2
        |--- 子包(子文件夹)
            |--- __init__.py  包的标志文件
            |--- 子包模块1
            |--- 子包模块2
    

    如何导入包?

    例1

    • 直接导入一个包:import package_name
    • 可以使用 __init__.py 中的内容,但 __init__.py 中一般为空
    文件结构
    |---pkg1
        |--- __init__.py
        |---
    |---use_pkg1.py
    
    示例
    # __init__.py
    def in_init():
        print("I am in init of package.")
    
    # use_pkg1.py
    import pkg1
    
    pkg1.in_init()
    

    例2

    • 简化包名
    • 此种方法默认导入 __init__.py 内容
    # use_pkg2.py
    import pkg1 as p
    
    p.in_init()
    

    例3

    • import package_name.module_name
    文件结构
    |---pkg1
        |--- __init__.py
        |--- student.py
        |---
    |---use_pkg3.py
    
    示例
    # use_pkg3.py
    import pkg1.student
    
    stu = pkg1.student.Student("Tom")
    stu.say()
    print(stu.age)
    
    pkg1.student.say_hello()
    

    例4

    • from package_name import module_name
    • 这种导入方法不执行 __init__.py 中的内容
    # use_pkg4.py
    from pkg1 import student
    
    stu = student.Student("Tom")
    stu.say()
    print(stu.age)
    
    student.say_hello()
    

    例5

    • from package import module1, module2, module3, ...
    • 导入包中指定的模块的所有内容

    例6

    • from package_name import *
    • 导入当前包 __init__.py 文件中所有的类和函数

    例7

    • from package_name.module import *
    • 导入包中指定模块的所有内容

    __all__

    • 在使用 from package import * 的时候,* 可以导入的内容与 __all__ 有关
    • __init__.py 中没有内容,或没有 __all__,则只能导入 __init__ 中的内容
    • __init__.py 设置了__all__的值,那么按照 __all__ 指定的子包或者模块进行加载,此时不会载入 __init__ 中的其他内容

    文件结构

    |---pkg1
        |--- __init__.py
        |--- student.py
        |---
    |---use_pkg.py
    

    示例

    # __init__.py
    __all__ = ['module1', 'module2', 'package1', ...]
    
    
    def in_init():
        print("I am in init of package.")
    
    # use_pkg.py
    from pkg1 import *
    
    stu = student.Student("Tom")
    stu.say()
    print(stu.age)
    
    student.say_hello()
    

    补充

    • 在开发中,经常会所以用其他模块,可以在当前包中直接导入其他模块中的内容
    • 使用 import 包或者模块的绝对路径

    命名空间

    • 用于区分不同位置不同功能但相同名称的函数或者变量的一个特定前缀
    • 防止命名冲突
    setName()
    Student.setName()
    Teacher.setName()
    
  • 相关阅读:
    通过elasticsearch对日志进行搜索热词统计
    登陆获取shell时的配置文件加载过程
    linux共享库加载
    linux安全相关
    ELK常用API使用方法
    linux bash缓存
    redis主从架构及redis集群
    排查电脑的网络问题
    Logstash添加Protobuf解析插件
    Macaca上手体验
  • 原文地址:https://www.cnblogs.com/yorkyu/p/12013265.html
Copyright © 2020-2023  润新知