python中,导入不同包中的模块、变量__all__以及包中__init__.py

基础概念:

  • 模块(Module):就是.py文件,里面定义了一些变量、函数、类等,需要的时候就可以导入这些模块。
  • 包(Package):在模块之上的概念,为了方便管理而将文件进行打包。包目录下的第一个文件便是__init__.py(这个文件可以看作包的标志),然后是一些模块文件和子目录,如果子目录中也有__init__.py,那么它就是这个包的子包。
    常见的包结构:
    在这里插入图片描述
  • 库(Lidbrary):具有相关功能模块的集合。这也是Python的一大特色之一,即具有强大的标准库、第三方库以及自定义模块。库分为标准库和第三方库。标准函数库(内置函数库):python中默认支持的函数库,要注意的是,里面有一些模块是看不到的。比如。sys模块,这与linux下的cd命令看不到是一样的情况。第三方库:就是由其他的第三方机构,发布的具有特定功能的模块。自定义模块:用户自己可以自行编写模块,然后使用。
    总结:这三个概念实际上都是模块,只不过是个体和集合的区别。

1.同一目录下的import(同在一个包的情况)

比如,我们要在test.py 中导入log_in.py ?

  • log_in.py 模块如下:
# 变量
a = 1
b = "abc"


# 函数
def func1(x, y):
    """计算两数的和"""
    print("login模块函数: ", x + y)


# 类
class Login():
    """验证用户名和密码是否一致"""

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def lojin(self, uname, pwd):
        if (self.username == uname) and (self.password == pwd):
            print("登录成功!")
        else:
            print("登录失败!")
  • test.py模块如下:
# 从同级目录(同一个包中的模块)导入模块,直接 import 模块名
import log_in

# 调用 log_in.py 中的变量,需要用模块名来调用
print(log_in.a)
print(log_in.b)

# 调用 log_in.py 中的函数,需要用模块名来调用
log_in.func1(3, 7)
  • 结果:
    在这里插入图片描述
  • 总结:在同一目录下导入模块,直接 import 模块名

2.导入不同包中的模块

如果我们要导入的模块在不同的包中,该如何导入?

1.概述:
from 包名 import 模块名from 包名.模块名 import 模块中的部分代码(如变量、函数、方法、类等) 后者中导入的变量,函数,类用“,”分隔。

方式一:导入整个模块,即 from 包名 import 模块名
目录结构如下,package01包(test.py在其中(模块名一般小写))和package02包(log_in.py在其中):

  • 架构
    在这里插入图片描述

  • log_in.py模块如下:

# 变量
a = 1
b = "abc"

# 函数
def func1(x, y):
    """计算两数的和"""
    print("login模块函数: ", x + y)

# 类
class Login():
    """验证用户名和密码是否一致"""
    
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def lojin(self, uname, pwd):
        if (self.username == uname) and (self.password ==pwd):
            print("登录成功!")
        else:
            print("登录失败!")
  • my_test.py模块如下:
# 从包 package02中导入 log_in 模块
from package02 import log_in

# 调用 log_in.py 中的变量,需要用模块名来调用
print(log_in.a)
print(log_in.b)

# 调用 log_in.py 中的函数,需要用模块名来调用
log_in.func1(3, 7)

# 调用 log_in.py 中的类,需要用模块名来调用
lg = log_in.Login("admin", "123456")
lg.lojin("admin1", "abcefg")

总结:使用 from 包名 import 模块名的方式,可以在其他的文件中导入包中的一个模块(导入整个模块),当要调用该模块中的代码时,需要用该模块的模块名称来调用。

  • 运行结果如下:
    在这里插入图片描述
      缺点:当调用模块中的部分具体代码时,都要用 模块名.xxx 的方式调用;
    方式二:导入模块中的某些部分,可以用 from 包名.模块名 import 模块中的部分代码(变量或函数或类)
  • 此时my_test.py中的代码:
# 通过 from 包名.模块名 import 变量或函数或类等
# 从 package02 的 log_in 模块中导入变量a 和 Login类
from package02.log_in import a, Login  # 逗号分隔
 
# 调用 log_in.py 中的变量,可直接调用
print(a)

print(b)  # 未导入 b 变量,直接调用报错

func1(3, 7)  # 未导入 func1 函数,直接调用报错

# 调用 log_in.py 中的类,可直接调用
lg = Login("admin", "123456")
lg.lojin("admin1", "abcefg")
  • 总结:
      1、若要导入一个模块中的多个属性(比如,变量、函数、类等),可以用英文逗号分隔;
      2、当导入模块中的所有属性时,可以用通配符“ * ”;也可以在使用该通配符时对导入属性范围进行限定:只要在被导入的模块中(.py文件中),对**_ all 属性进行范围赋值,如 all =[a,func1, Login]**,那么用通配符“ * ”导入该模块中的所有代码时,只会导入 all _ 属性限定范围内的那些;
      
      原文:https://www.cnblogs.com/leolsl/p/13159426.html

方式三 :import xxx

当要采用import 模块名的方式导入不同包中的模块,首先,使用
import sys sys.path.append("被导入包的目录")将被导入的模块的路径添加到解释器的搜索路径中,再import 模块名

  • 此时my_test.py中的代码:
import sys
# 将package02 的搜索路径也加入解释器
sys.path.append(r"E:\test\package02")  # window 中加入了"r",保持字符串的原样输出
# 上面的等同的写法:sys.path.append("E:\test\package02")  # "\"转义字符
import log_in


# 调用 log_in.py 中的变量,需要用模块名来调用
print(log_in.a)
print(log_in.b)

# 调用 log_in.py 中的函数,需要用模块名来调用
log_in.func1(3, 7)

# 调用 log_in.py 中的类,需要用模块名来调用
lg = log_in.Login("admin", "123456")
lg.lojin("admin1", "abcefg")
  • 结果:
    在这里插入图片描述
    注意:这种导入的方式,由于 import 的路径只是标准库以及自己的目录,故在搜索前要把模块所在的目录添加进搜索路径 ,然后再import

3. __all__变量用法

作用
__all__是一个字符串list(元素是字符串的列表),用来定义模块中对于采用 from XXX import * 的方式导入时要对外导出的符号,即要暴露的借口,注意:它只对 import *的导入方式起作用,对 from XXX import XXX不起作用。

1.模块中的__all__

此时__all__中的元素是此模块中暴露给外界的一部分信息(比如,变量,函数,某个类等)
1.验证
代码结构如下:
package01(包)中包含了__init__.py(相当于包的标志,后谈)、main.py(测试文件)以及my_test.py(被导入测试文件的模块)
在这里插入图片描述

  • my_test.py(被导入的模块):
# 当使用通配符“*” 导入时,限定可以被导入的部分,别的导入方式不起作用
__all__ = ['x', 'test', 'Login']  

# 变量
x = 1
y = 2
z = 3

# 函数
def test():
    print("———test---")
    
def test1():
    print("---test1---")

# 类
class Login():
    """验证用户名和密码是否一致"""

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def lojin(self, uname, pwd):
        if (self.username == uname) and (self.password == pwd):
            print("登录成功!")
        else:
            print("登录失败!")        
  • main()测试文件:
from package01.my_test import *  # import *的导入方式
# 调用__all__ 中包含的代码,可行
print(x)
test()
  • 运行结果:
    在这里插入图片描述
    2.总结:当使用通配符导入包含__all__的模块时,只有__all__中包含的那些才可以被导入,否则结果如下:
  • 修改后的main.py(在其中调用__all__中不包含的代码)
from package01.my_test import *
# 包含
print(x)
test()

# 导入__all__中不包含的代码
test1()
lg =Login("admin", "123456")
lg.lojin("admin1", "abcefg")

运行结果:
在这里插入图片描述

2.init__中的__all

此时的__all__中的元素是暴露给外界的模块名
此时的架构:
在这里插入图片描述

  • A.__init__:
# 这个包中可以被别的文件导入的模块
__all__ = ['my_module2']
  • A.my_module1:
def info_print1():
    print("my_module1")


# # 测试代码
# info_print1()
# 改进的代码测试,当该文件被导入到别的文件时,这部分代码不会执行,一般的测试代码书写于此
if __name__ == "__main__":
    info_print1()
  • A.__init__:
# 这个包中可以被别的文件导入的模块
__all__ = ['my_module2']
  • A.my_module2:
def info_print2():
    print("my_module1")


# # 测试代码
# info_print2()
# 改进的代码测试,当该文件被导入到别的文件时,这部分代码不会执行,一般的测试代码书写于此
if __name__ == "__main__":
    info_print2()
  • ``
    **1.
      参考:https://www.jianshu.com/p/ca469f693c31

4.package 中的__init__.py文件

1.init.py的主要作用:
1.Python中 package 的标识;
2.在__init__.py 中定义__all__用来模糊导入;
3.编写 Python 代码(不建议这么做,实际的逻辑可以在其他py文件中写,init.py应该尽量轻)。
参考:https://blog.csdn.net/qaning1472/article/details/85918341?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值