[日常] Python 模块/包的导入以及函数参数传递详解

目录

  1. Python 模块/包的导入
  2. Python 函数参数传递

1. Python 模块/包的导入

Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
Python 包(Package)是一个分层次的文件目录结构,由模块和子包等组成的 Python 的应用环境。简单来说,包就是一个包含 init.py 文件的文件夹。
详细情况,可以阅读官方文档。

1.1 模块的导入

  • 常用导入语句:

    import xxx 
    import xxx, xxx, xxx
    import xxx as xxx
    from xxx import xxx
    from xxx import xxx as xxx
    from xxx import * # 如果目标模块有定义列表__all__,则from module import * 语句只能导入__all__列表中存在的对象。
    
    
  • Python import 的搜索路径:

    Python 解析器对模块位置的搜索顺序:
    (1) 先搜索当前目录
    (2) 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
    (3) 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
    模块搜索路径存储在 system 模块的 sys.path 变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

  • 如何解决 ModuleNotFoundError:

    出现该错误往往由于两个原因导致:无相对应的模块文件,目标模块文件所在路径不在模块搜索路径中。
    解决后者仅需将目标模块文件所在路径添加进模块搜索路径中即可(假设目标模块在当前目录的上级目录中):

    import os
    import sys
    
    currentPath = os.path.dirname(__file__) # 返回该代码文件所在文件夹的路径
    parentPath = os.path.abspath(os.path.join(currentPath, os.path.pardir)) # 返回当前文件的父目录的绝对路径
    
    #把目标路径添加到 path 下,即可引入该路径下的模块
    sys.path.append(parentPath)
    

1.2 包的导入

假设目标包的结构为:

package
|---__init__.py
|---a.py
|---b.py
|---subpackage1
           |---__init__.py
           |---a.py
           |---b.py
|---subpackage2
           |---__init__.py
           |---a.py
           |---b.py
  • 常用的导入命令:

    import package # 仅导入 package 包,自动调用 __init__.py 文件,无法调用 package.a/package.b
    from package import a # 导入 package 包中的模块 a,并自动调用 __init__.py 文件
    from package import subpackage1 # 仅导入 package 包中的 subpackage1 子包
    from package.subpackage1 import a # 导入 package 包中的 subpackage1 子包下的模块 a
    
  • 相对导入与绝对导入:

2. Python 函数参数传递

先说结论:在 Python 中所有函数的参数都是按引用(地址)传递

有的人就会提出疑问:如果是按引用(地址)传递,为何在下面的例子中,所传入的参数没有被改变?

def test(a):
    a = 10

if __name__ == "__main__":
	a = 100
	test(a)
	print(a)

代码运行结果:

100

这个例子就涉及到 Python 的可变对象(Mutable)和不可变对象(Immutable)。
在 Python 中,可变对象与不可变对象分别有:

  • 可变对象:list, dict, set
  • 不可变对象:tuple, string, int, float, bool

注意,Python 是动态语言,其中的变量并没有类型这一概念,只有对象才存在类型这一概念

在上面的例子中,所传递的参数为变量 a 所指向的对象的地址,该对象为不可变对象,故对其进行重新赋值时,Python 会重新在内存中创建新的 int 对象,并将函数 test 中的局部变量 a 指向该对象,故全局变量 a 未受到其影响。

若仍有疑问,可运行下面的代码:

def test(a):
    print(2, id(a))
    a = 100
    print(3, a)
    print(4, id(a))

if __name__ == '__main__':
    a = 10
    print(1, id(a))
    test(a)
    print(5, a)
    print(6, id(a))

代码运行结果:

1 4419290832
2 4419290832
3 100
4 4419291152
5 10
6 4419290832

参考资料:

  • Python 模块
  • Python 相对导入与绝对导入
  • Python导入模块的几种姿势
  • python模块及包的导入
  • Python的函数参数传递:传值?引用?
  • Python 的函数是怎么传递参数的?

如果你看到了这篇文章的最后,并且觉得有帮助的话,麻烦你花几秒钟时间点个赞,或者受累在评论中指出我的错误。谢谢!

作者信息:
知乎:没头脑
CSDN:Code_Mart
Github:Tao Pu

你可能感兴趣的:(Python)