暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

python模块命名空间嵌套重载

原创 梯阅线条 2023-10-14
76

python模块命名空间嵌套重载

1 python模块使用事项

1.1 python模块导入只执行一次

描述

python模块在首次导入时从上到下执行模块内容,再次导入直接从内存取数据,不会再从上到下执行。

示例

# runonce.py s='梯阅线条' print('执行一次:{}'.format(s)) # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) # 首次导入模块,从上到下执行模块内容 >>> import runonce as ro 执行一次:梯阅线条 >>> ro.s '梯阅线条' >>> ro.s='tyxt' # 再次导入模块,不执行模块内容,直接从内存读取 >>> import runonce as ro >>> ro.s 'tyxt'

1.2 import和from是赋值语句

描述

python导入模块的import和from都是隐性赋值语句。类似def。

NO 描述
1 import将模块对象赋值给模块名
2 from将模块属性值赋给当前模块的同名变量。

修改导入模块内的对象

NO 操作 描述
1 修改可变对象 imort或from导入模块,通过“模块.属性=值”或“变量=值”修改可变对象。
2 修改不可变对象 import导入模块,通过“模块.属性=值”修改不可变对象。

示例

# assing.py s='梯阅线条' L=[s,9555] # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) >>> from assign import s,L >>> s,L ('梯阅线条', ['梯阅线条', 9555]) >>> s='tyxt';L[1]=2023 >>> import assign # 导入可变对象被修改时,模块内对象跟着被修改 >>> assign.s,assign.L ('梯阅线条', ['梯阅线条', 2023]) >>> s,L ('tyxt', ['梯阅线条', 2023]) # 使用import 模块,再通过“模块.属性=值”修改模块内不可变对象 >>> assign.s=s >>> assign.s,assign.L ('tyxt', ['梯阅线条', 2023])

1.3 使用import场景

描述

如果导入的多个模块中,存在同名属性,则需使用import进行导入。

示例

# mod_5.py def myprint(val): print('在mod_5:{}'.format(val)) # mod_6.py # mod_6.py def myprint(val): print('在mod_6:{}'.format(val)) # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) >>> s='tyxt' # from语句,多个模块中,导入同名属性,只会执行最后导入的属性 >>> from mod_5 import myprint >>> from mod_6 import myprint >>> myprint(s) 在mod_6:tyxt # import导入多个模块中的同名属性,通过“模块.属性”访问各自同名属性 >>> import mod_5,mod_6 >>> mod_5.myprint(s) 在mod_5:tyxt >>> mod_6.myprint(s) 在mod_6:tyxt

2 python模块命名空间

python模块为.py文件,导入模块会创建模块对象,模块文件的顶层变量为模块属性。

python的命名空间(namespace)是指从名称到对象的映射。

对象=f(名称),f为命名空间。

任何一个名称,通过命名空间f,都能找到唯一一个对象与之对应。

python变量名的创建、修改和查找都是在命名空间进行的。

python模块命名空间就是模块对象存放全部模块内变量名的场所。

任何一个模块属性名称都可以通过模块命名空间找到唯一一个对象与之对应。

通过“模块.属性名”或“属性名”的方式进行访问。

2.1 python模块生成命名空间

描述

python模块文件顶层变量名包括:函数名、类名、函数外部变量名、类外部变量名,都为模块属性。通过“模块.变量名”方式访问。

python模块生成命名空间:

NO 内容 描述
1 首次导入执行模块语句 首次导入模块创建空模块对象,从上到下执行模块内语句。
2 顶层赋值语句为模块属性 顶层变量赋值语句的变量名成为模块属性,比如:=(def和class外的等于号)、def、class、import、from、as等
3 __dict__获取模块命名空间 模块命名空间为字典,通过__dict__获取属性及值。

示例

# modnames.py print('执行模块语句开始') import sys s='梯阅线条' def modf(): x='modf' class modc(object): y='modc' print('执行模块语句结束') # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) # 从上到下执行模块语句 >>> import modnames 执行模块语句开始 执行模块语句结束 # 顶层变量赋值成为属性:import赋值语句 >>> modnames.sys <module 'sys' (built-in)> # 顶层变量赋值成为属性:def、class 外等于号 = >>> modnames.s '梯阅线条' # 顶层变量赋值成为属性:def 隐性赋值 >>> modnames.modf <function modf at 0x0400DF18> # 顶层变量赋值成为属性:class 隐性赋值 >>> modnames.modc <class 'modnames.modc'> # 非顶层变量赋值不能成为属性:defclass 内赋值 >>> modnames.x Traceback (most recent call last): File "<pyshell#9>", line 1, in <module> modnames.x AttributeError: module 'modnames' has no attribute 'x' >>> modnames.y Traceback (most recent call last): File "<pyshell#11>", line 1, in <module> modnames.y AttributeError: module 'modnames' has no attribute 'y' # 通过 __dict__ 字典存储命名空间的属性 >>> list(modnames.__dict__.keys()) ['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', 'sys', 's', 'modf', 'modc'] >>> modnames.__dict__['s'] '梯阅线条' # __file__ : 获取模块文件路径 >>> modnames.__dict__['__file__'] 'E:\\documents\\F盘\\modnames.py'

2.2 python点号属性名运算

python点号属性名为表达式运算,返回和属性名匹配的值。

NO 内容 描述
1 无点号,X 简单变量,按LEGB规则在当前作用域内搜索变量名X
2 单点号,X.Y 当前作用域搜索X,搜索对象X的Y属性
3 多点号,X.Y.Z 搜索对象X的Y属性,搜索X.Y对象的Z属性

点号运算适用于有属性的任何对象,比如:方法、模块、类等对象。

2.3 python导入作用域

描述

python作用域由程序位置决定,不受模块导入和函数调用影响。

NO 内容 描述
1 被导入文件无法访问进行导入的文件内的变量名 mod2.py导入mod1.py,那么mod1.py是无法访问mod2.py内的变量的。
2 函数无法访问其他函数内的变量名,除法物理上的嵌套函数 函数fa()是无法方法函数fb()内的变量的,除非fa()是fb()的内部函数。
3 模块无法访问其他模块内的变量名,除非导入模块 模块mod1.py是无法访问模块mod2.py内的变量的,除非模块mod1.py导入模块mod2.py

示例

# mod_a.py s='梯阅线条' def modaf(): global s s = 'tyxt' # mod_b.py s='软件测试开发' import mod_a mod_a.modaf() print(s,mod_a.s) # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) # 被导入的模块 mod_a,不可访问模块 mod_b 的变量s >>> import mod_b 软件测试开发 tyxt

2.4 python模块嵌套

描述

python模块a导入模块b,模块b导入模块c,那么模块a可以访问模块c的属性。

示例

# modc.py s='modc' # modb.py s='modb' import modc print('modb执行 s:{}'.format(s)) print('modb执行 modc.s:{}'.format(modc.s)) # moda.py s='moda' import modb print('moda执行 s:{}'.format(s)) print('moda执行 modb.s:{}'.format(modb.s)) print('moda执行 modb.modc.s:{}'.format(modb.modc.s)) # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) >>> import moda # moda 导入 modb,从上到下执行modb modb执行 s:modb modb执行 modc.s:modc # 导入 moda, 从上到下执行 moda moda执行 s:moda moda执行 modb.s:modb # 访问通过modb导入的modc:modb.modc.s moda执行 modb.modc.s:modc

3 python模块重载

python模块导入后,再次导入不会重新加载和执行模块文件代码。

python的reload函数,强制已加载的代码重新加载和执行,让模块动态更新。

3.1 python模块重载reload

用法

import moda from importlib import reload reload(moda)

描述

python的reload()函数需先从importlib导入。

reload**(moda)****:**moda为模块对象,即需先导入moda才能进行reload。

NO 描述
1 reload在当前命名空间执行新代码,不会删除重建命名空间。
2 执行有变化的顶层赋值语句。
3 reload会更新import导入的客户端的引用。
4 reload不更新from导入的客户端的引用,因为from是复制属性,最新的值只有在from客户端重启后生效。

示例

# reloadmod.py s='梯阅线条' def reloadf(): print(s) # idle执行下面语句 >>> import os >>> path=r'E:\documents\F盘' >>> os.chdir(path) >>> from importlib import reload # 未导入模块不可进行 reload 操作 >>> reload(reloadmod) Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> reload(reloadmod) NameError: name 'reloadmod' is not defined >>> import reloadmod >>> reloadmod.reloadf() 梯阅线条 # 修改reloadmod.py的 s=’tyxt’ # reloadmod.py s='tyxt' def reloadf(): print(s) # idle执行下面语句 # import取内存的旧数据 >>> import reloadmod >>> reloadmod.reloadf() 梯阅线条 # reload 执行更新的模块文件 >>> reload(reloadmod) <module 'reloadmod' from 'E:\\documents\\F盘\\reloadmod.py'> >>> reloadmod.reloadf() tyxt

4 END

本文首发微信公众号:梯阅线条

更多内容参考python知识分享或软件测试开发目录。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论