python包相关知识点之包的导入、相对路径以及绝对路径

 更新时间:2022年04月26日 09:59:55   作者:一二三四!  
Python的好处在于你不需要懂很多概念,你就有机会投入工作,同样问题也有机会随时发生,下面这篇文章主要给大家介绍了关于python包相关知识点之包的导入、相对路径以及绝对路径的相关资料,需要的朋友可以参考下

一、包

在我们的项目中,可能会有太多的模块

但是我们不能把所有的模块这样放在这里,这样项目会乱七八糟。

我们可以将所有相同类型的模块放在一个文件夹中,这个文件夹就叫做包

包就是文件夹,他用于存放文件也就是模块。包中也可以存放包

包就是一个包含了__init__.py文件的文件夹。

包只是模块的一种形式而已,包即模块。

包的结构:


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

二、包的导入

1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如demo0demo02.demo03,但都必须遵循这个原则。

2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

3.对比import demo和from demo import name的应用场景:

如果我们想直接使用name那必须使用后者。

1.import 导入

在demo01_test02.py 中 导入 demo01_test01.py

demo01_test01.py 源码:

def say():
    print('demo01_test01_hello')
 
name = '赵四'

demo01_test02.py 源码:

import base.demo01.demo01_test01
base.demo01.demo01_test01.say()    #  调用test01中的say方法 输出 demo01_test01_hello
import sys
print(sys.path)
#['D:\\pycharm工作空间\\day12\\base\\demo01', 'D:\\pycharm工作空间\\day12', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend']

2.from...import...导入

from 包名.模块名... import 变量名

使用方式: 例如 变量名() 或者print(变量名)

demo01_test02.py 源码:

from base.demo01.demo01_test01 import say
say() # demo01_test01_hello

from 包名.模块名... import 变量名1,变量名2,...

使用方式: 例如 变量名1() 或者print(变量名2)

demo01_test02.py 源码:

from base.demo01.demo01_test01 import say,name
say()
print(name)  # 调用test01中的name变量

from 包名 import 模块名

使用方式:模块名.变量名() 或者 print(模块名.变量名)

demo01_test02.py 源码:

from base.demo01 import demo01_test01
demo01_test01.say() # demo01_test01_hello

from 包名 import 模块名,模块名1...

使用方式:模块名.变量名() 或者 print(模块名1.变量名)

在demo01_test02.py中调用demo02_test01.py, demo02_test02.py 源码

demo02_test01.py 源码:

def say21():
    print('demo02_test01_hello')

 demo02_test02.py 源码:

def say22():
    print('demo02_test02_hello')

demo01_test02.py 源码:

from base.demo02 import demo02_test01,demo02_test02
demo02_test01.say21() # demo02_test01_hello
demo02_test02.say22() # demo02_test02_hello

需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法 

from base.demo02 import demo02_test02.say
# 报错 SyntaxError: invalid syntax

3.__init__.py文件

不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。

demo1下的__init__.py文件源码:

print('啦啦啦')

demo01_test02.py 源码:

from base.demo01 import demo01_test01
 
demo01_test01.say()
# 啦啦啦     __init__.py中的代码执行结果
# demo01_test01_hello

4.from 包.模块 import *

此处是想从包demo02中导入所有,实际上该语句只会导入包demo02下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

demo02下__init__.py文件的源码:

print('呜呜呜')
name = '王大夫'

 demo01_test02.py 源码:

from base.demo02 import *
 
print(name) # 王大夫
demo02_test01.say() # 报错 无法调用
# 输出:  呜呜呜
# NameError: name 'demo02_test01' is not defined

在demo02下的__init__.py文件中加入以下源码:

print('呜呜呜')
name = '王大夫'
 
__all__ = ['demo02_test01','demo02_test02']

再调用:

from base.demo02 import *
 
demo02_test01.say21()   #  成功调用
print(name) # 报错 变量name没有定义
 # 呜呜呜
 # demo02_test01_hello

三、包的相对和绝对导入

我们的最顶级包base是写给别人用的,然后在base包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

绝对导入:以base作为起始

相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

1. 绝对导入

在demo01中的demo01_test02.py中调用demo02中的模块

from base.demo01 import demo01_test01
demo01_test01.say()    

在 base目录下的py文件中调用demo01_test02.py

from base.demo01 import demo01_test02
demo01_test02.demo01_test01.say()

2.相对导入

在demo01中的demo01_test02.py中调用demo02中的模块

from ..demo02.demo02_test01 import say21
say21()

在 base目录下的py文件中调用demo01_test02.py 

from base.demo01 import demo01_test02
 
demo01_test02.say21()
import sys
print(sys.path)
'''
啦啦啦
呜呜呜
demo02_test01_hello
demo02_test01_hello
['D:\\pycharm工作空间\\day12\\base', 'D:\\pycharm工作空间\\day12', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend']
'''

相对路径运行注意事项:

在没有明确指定包结构的情况下,Python 是根据 __name__ 来决定一个模块在包中的结构的,如果是 __main__ 则它本身是顶层模块,没有包结构,如果是base.demo01.demo02 结构,那么顶层模块是 base。

如果是相对导入,一个模块必须有包结构且只能导入它的顶层模块内部的模块

如果一个模块被直接运行,则它自己为顶层模块,不存在层次结构,所以找不到其他的相对路径。

 四、import 导入自定义包的子模块

特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入

demo03中的test01源码:

def test():
    print('这是一个测试方法')

直接运行demo03_test02模块

import test01
 
test01.test()
 
import sys
print(sys.path)
'''这是一个测试方法
['D:\\pycharm工作空间\\day12\\base\\demo03', 'D:\\pycharm工作空间\\day12', 'D:\\pycharm工作空间\\day12\\base\\demo03', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend']
'''

不会报错因为sys.path中已经添加了day05-包/demo03路径。Import会从sys.path中依次搜索路径。

在base目录下导入demo03_test02.py进行使用

from base.demo03 import test02
# 报错 ModuleNotFoundError: No module named 'test01'

因为此时的sys.path中只有demo01-包.py的路径 .../day05-包,import demo03_test01 只能从/day05-包下查找 demo03_test01模块。找不到因此报错。 

解决import 导入包时的报错问题

我们可以在sys.path中添加import搜索的路径。

import sys,os
path = os.path.abspath(__file__)
print(path)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
print(BASE_DIR)
sys.path.append(BASE_DIR)
print(sys.path)
import base.demo03.test01
base.demo03.test01.test()  # 这是一个测试方法

五、包的单独导入

单独导入包名称时不会导入包中所有包含的所有子模块

import base.demo03
 
base.demo03.test01.test()
# 报错  AttributeError: module 'base.demo03' has no attribute 'test01'

解决办法:需要从__init__.py中进行初始化操作 

进行上诉操作后:

六、包的安装和发布

1、在包的同级目录创建 setup.py

from distutils.core import setup
 
setup(name='bag',
      version='1.0,3',
      description='描述:这是我的第一个包',
      author='zxb',
      author_email='505555162@qq.com',
      py_modules=['test1', 'test2'],
      )

2.在命令行 运行 python setup.py build (可以不执行 ) 

构建模块  

 

4.生成发布的压缩包 运行 python setup.py sdist

5、安装包

导入自己的包进行测试

测试成功!!

包的卸载: 直接找到对应的位置删除即可。

总结

到此这篇关于python包相关知识点之包的导入、相对路径以及绝对路径的文章就介绍到这了,更多相关python包的导入、相对及绝对路径内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python2随机数列生成器简单实例

    Python2随机数列生成器简单实例

    这篇文章主要介绍了Python2随机数列生成器,结合简单实例形式分析了Python基于random模块操作随机数的相关实现技巧,需要的朋友可以参考下
    2017-09-09
  • Python中的min及返回最小值索引的操作

    Python中的min及返回最小值索引的操作

    这篇文章主要介绍了Python中的min及返回最小值索引的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • pycharm远程调试openstack代码

    pycharm远程调试openstack代码

    这篇文章主要为大家详细介绍了pycharm远程调试openstack的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • python使用typing模块加强代码的可读性(实战演示)

    python使用typing模块加强代码的可读性(实战演示)

    Python是一门弱类型的语言,很多时候我们可能不清楚函数参数类型或者返回值类型,很有可能导致一些类型没有指定方法,typing模块可以很好的解决这个问题。下面通过本文给大家介绍python使用typing模块加强代码的可读性,感兴趣的朋友一起看看吧
    2021-12-12
  • python3在各种服务器环境中安装配置过程

    python3在各种服务器环境中安装配置过程

    这篇文章主要介绍了python3在各种服务器环境中安装配置过程,源码包编译安装步骤详解,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • Python中title()方法的使用简介

    Python中title()方法的使用简介

    这篇文章主要介绍了Python中title()方法的使用简介,是Python入门中的基础知识,需要的朋友可以参考下
    2015-05-05
  • 浅析python继承与多重继承

    浅析python继承与多重继承

    在本篇文章中我们给大家分析了python继承与多重继承的相关知识点内容,有兴趣的读者们参考下。
    2018-09-09
  • pytorch 膨胀算法实现大眼效果

    pytorch 膨胀算法实现大眼效果

    在PS中,我们可以利用液化工具对人像进行瘦脸、放大眼睛等系列的常规操作。今天我们来了解一下这些操作的算法原理,并用pytorch 膨胀算法来实现大眼效果,感兴趣的可以了解一下
    2021-11-11
  • Python动态参数/命名空间/函数嵌套/global和nonlocal

    Python动态参数/命名空间/函数嵌套/global和nonlocal

    这篇文章主要介绍了Python动态参数/命名空间/函数嵌套/global和nonlocal,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • pandas删除部分数据后重新生成索引的实现

    pandas删除部分数据后重新生成索引的实现

    这篇文章主要介绍了pandas删除部分数据后重新生成索引的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论