Python-最详细模块/包的(动态)导入

目录

前言

模块导入

什么是模块?

import

搜索路径

as

 dir

__name__

from xxx import ...

包导入

命名空间

包中模块的import

动态导入

内置函数 __import__()

importlib

参考


前言

你是否会出现下图中导模块时找不到的情况呢?

ModuleNotFoundError,也就是模块没有找到,不要慌,今天总结导包的所有问题。

模块导入

什么是模块?

容器->数据的封装

函数->语句的封装

类一>方法和属性的封装

模块->模块就是程序,.py文件就是模块

import

import sys

 import sys就没有错了,这是为什么呢?这就要提到搜索路径了

搜索路径

print(sys.path)

我们打印出了搜索路径,接下来就看看里面有什么

 在其中的一个路径下面有sys,也就是说.py文件所在目录在sys.path中就可以了,我们看到第一个路径就是当前的包路径,在needmodule.py同级目录下写xxx.py就可以了

xxx.py

print("I'm xxx,welcome to import me, i have a hi function")


def hi():
    print(f'hi!')
import xxx
xxx.hi()

我们可以导入,并且使用里面的函数

as

如果模块的名字很长,我们可以改个别名

import xxx as x
x.hi()

 dir

使用dir函数,可以查看模块里面有什么

有一些默认的,__name__就是模块名字,__doc__是一些说明文字,其他的可以自行探索

忘记列表有哪些函数,就可以使用dir查看一下

>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] 

__name__

刚才提到了__name__,这是一个很特殊的属性,你开发模块时可能进行一些测试,如果有些代码你想导入时不运行,你可以使用这个

运行xxx.py是,也就是xxx作为主要(main)文件,就会运行另一个分支的代码。

from xxx import ...

如果只想部分导入的话,如何做呢?例如,只想使用某个模块的某个函数,这是就需要使用from了

xxx.py中添加一个函数

def useful():
    print("I'm a useful function!!!")

 needmodule.py

from xxx import useful
useful()
hi()

 导入的可以使用,没导入的会报NameError

包导入

包:包含__init__.py的目录

在上面“搜索路径”一节,展示sys模块的时候,它就在一个包中,可以看到__init__.py文件,同样,xxx.py和needmodule.py在learn_mod_pak包中

命名空间

一般有三种命名空间:

  • 内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
  • 全局名称(global names)模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
  • 局部名称(local names)函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)

Python 的查找顺序为:局部的命名空间去 -> 全局命名空间 -> 内置命名空间

dir在内置命名空间,hi在全局命名空间,所以我们尽量不要和系统内置函数名一样

写一样的函数名,导致运行自己的函数(先在全局命名空间找),可能会出现一些错误。

通过一个例子,说明包的作用:假设你是李华,你的朋友叫小明,你很喜欢♂他,想要和他表白。于是,你告诉了学校广播站的同学,但是广播员广播时直接说了“小明,xxx年级的xxx班的李华喜欢你”。结果你喜欢的小明在二年级三班,另一个暗恋你的小伙子也叫小明,他在三年级四班。三年级四班的小明来找你...这就很尴尬。

上面的年级和班就类似包,模块就类似人,加上前缀就不会出错了,当然,一个包内的模块不能重名。

包中模块的import

needmodule.py

import hi.sayhi
from hello.sayhello import hello
hello()

包结构及结果如下

导入了hi包的sayhi模块,以及hello包的sayhello模块的hello函数。相对于前面导入模块,只需要 包名.模块名 即可

注意,包的__init__.py也是一个模块,它的名字就是对应的包名,当你导入包或包里面的东西时,__init__.py也被导入了

我们在hi包的__init__.py中加入一句话

print('我是hi包的__init__.py文件,我也是模块,我的名字就是hi')

先导入的hi模块,再导入的hi包的sayhi模块

动态导入

动态导入:程序执行时对导入的包进行导入和移除

内置函数 __import__()

__import__(name, globals=None, locals=None, fromlist=(), level=0)

该函数会导入 name 模块,有可能使用给定的 globalslocals 来确定如何在包的上下文中解读名称。 fromlist 给出了应该从由 name 指定的模块导入对象或子模块的名称。 标准实现完全不使用其 locals 参数,而仅使用 globals 参数来确定import语句的包上下文。level 指定是使用绝对还是相对导入。 0 (默认值) 意味着仅执行绝对导入。 level 为正数值表示相对于模块调用__import__()的目录,当 name 变量的形式为 package.module 时,通常将会返回最高层级的包(第一个点号之前的名称),而 不是name 命名的模块。 但是,当给出了非空的 fromlist 参数时,则将返回以 name 命名的模块。

__import__(module)相当于import module

__import__(package.module)相当于from package import name,如果fromlist不传入值,则返回package对应的模块,如果fromlist传入值,则返回package.module对应的模块。

程序刚开始没有导入sayhello模块,无法使用hello函数,所以报异常,导入后可以使用

importlib

这个包有一个import_module(name, package=None)函数,和__import__()有一些不同

这两个函数之间最重要的不同点在于import_module()返回指定的包或模块 (例如 pkg.mod),而__import__()返回最高层级的包或模块 (例如 pkg)。如果您只想按名称导入模块(可能在包中),请使用 import_module(name, package=None)

参考

模块与包

内置函数__import__()

import_module()

更多python相关内容:【python总结】python学习框架梳理

本人b站账号:lady_killer9

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。如果您感觉有所收获,自愿打赏,可选择支付宝18833895206(小于),您的支持是我不断更新的动力。

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lady_killer9

感谢您的打赏,我会加倍努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值