基础概念:
- 模块(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