python——高级模块话题
1.1 最小化from *的破坏
from *会把所有变量名复制出去,导入者可能得到超出它需要的分布(包括会覆盖导入者内的变量名的变量名)。
在__init__.py中使用__all__则可以保证from *语句只会把__all__列表中的这些变量名复制出来。另外对于模块中以_x形式的变量是指出不被复制的变量名。
1.2混合用法模型:__name__和__main__
每个模块都有一个名为__main__的内置属性,python会自动设置该属性:
- 如果文件是以顶层程序文件执行,在启动时,__name__就会设备为字符串"__main__"。
- 如果文件被导入,__name__就会改成客户端所了解的模块名。
结果就是模块可以检测自己的__name__,来确定他是执行还是在导入。
1.3 以__name__进行单元测试
这就是在pycharm中常用的方法:
if __name__ == '__main__': #这种语法来进行单元测试 import sys if len(sys.argv) ==1: # sys.argv列表包含了命令行参数,是一个字符串列表,其中你第一个总是将要运行的脚本名 print('without argv') else: print(sys.argv[1])
其实,更多的在平时看到的可能是使用argparse模块。argparse是一个命令行工具,具体用法如下:
# learn to using argparse and parse cmdline def parse_arg(): # generate a parse object,description will describe what's this parse resolver, # you can see this string when using help parser =argparse.ArgumentParser(description='this is a demo of argparse') # using add_argument to add argument, '-n' and '-name' are behalf of the same arg parser.add_argument('-n','--name',default='Ssozh',help='write down your name') # finally , use args get the arguments args = parser.parse_args() print(args) # Namespace(name='Ssozh') ,which means -n cannot represent argument name name = args.name # using name rather than n return name if __name__ == '__main__': name = parse_arg() print('hello {}'.format(name))
更详细的可以见另一篇博文:http://vra.github.io/2017/12/02/argparse-usage/
1.4 模块是对象:元程序
因为模型通过内置属性显示了它们的大多数有趣特性,因此,很容易编写程序来管理其他程序。我们通常称这类管理程序为元程序(metaprogram),因为它们是在其他系统之上工作的。
例如,我们编写了一个元程序用来查看模块a的内置属性,而模块(python文件)的内置属性使用属性字典保存,可以使用__dict__进行索引运算。
def listing(module, verbose=True): sepline = '-' * 60 # sepline = '________________' if verbose: print(sepline) # name: 123 file: D:\Ssozh\PyCharm\logo_test\module_demo.py print('name:', module.__name__, 'file:', module.__file__) print(sepline) count = 0 for attr in module.__dict__: # get the attr of module # 00)__name__ print('%02d)%s' % (count, attr), end=' ') if attr.startswith('_'): print('<built-in name>') # <built-in name> else: print(getattr(module, attr)) # this attr maybe variable count += 1 if verbose: print(sepline) # 123 has 8 names print(module.__name__, 'has %d names' % count) print(sepline)
1.5 模块设计理念
- 总是在Python的模块内编写代码。事实上,在交互模型提示符下输入的程序代码,其实是存在于内置模型__main__之内的。交互模型提示符独特之处就在于程序是执行后就立刻丢弃,以及表达式结果是自动打印的。
- 模块耦合要降到最低:全局变量。就像函数一样,如果编写成闭合的盒子,模块运行得最好。原则就是,模块应该尽可能和其他模块的全局变量无关,除了与从模块导入的函数和类。
- 最大化模块的黏合性:统一目标。可以通过最大化模块的黏合性来最小化模块的耦合性。如果模块的所有元素都享有共同的目的,就不太可能依赖外部的变量名。
- 模块应该少去修改其他模块的变量。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix