【python】argparse解析参数的过程

news2024/11/17 8:43:12

python基础知识

  • python文件解析
  • if \_\_name\_\_ == '\_\_main\_\_'的作用
  • import到底导入了什么?
  • argparse解析命令行参数的过程
  • Debug—案例分析

python文件解析

Python和C语言的编译、执行过程有很大区别。我们先回顾一下c语言的执行过程,首先代码文件要编译,编译通过(没有报错)后才能执行——此时执行的已经不是原始的代码文件了,而是二进制可执行文件。 但是python文件,不是对整个代码文件先编译再执行的——运行python文件,比如命令行输入python mytest.py,解析器会从mytest.py文件的第一行开始逐行解析并执行。

总结来说:

  • C语言是静态编译的,即源代码在编译阶段被翻译成机器码,然后在运行时直接执行机器码。
  • Python是解释执行的,源代码在运行时被解释器逐行解释执行,不会直接编译成机器码。

这两种编译方式的差异,使得在C语言中变量和函数都可以先声明后使用,比如一个func1()你只要先声明了,就能使用,不管实际定义(函数体)的位置在哪里;但在Python却不行,你必须先定义一个函数,才能使用,否则就会报错。

另外,Python文件中顶格的代码,即顶层的代码是会被直接执行的;定义的class、function等只有在调用的时候才执行。

if __name__ == '__main__'的作用

python一个文件可以作为一个模块(module),一个python文件利用import机制可以引用另一个文件的部分代码,比如p2.py中用import引用p1.py定义的一个class、function等等,这样在p2.py中就能运行p1.py文件的代码,实现代码复用。

那么当p1.py的部分代码(比如针对p1.py的测试代码),只在该文件被直接运行时被执行,而不会在执行p2.py文件的时候被调用,就可以放在if __name__ == '__main__': 条件模块下。 __name__是python内置的一个特殊变量 :

  • 当python文件作为主文件直接执行时,__name__ == ‘__main__’;
  • 当python文件被import到其他文件时,__name__ ==’ __文件名__';

假设p1.py内容如下:

print("1-This is p1.py file~")
def main():
    print("1-This is main() function in p1.py~")
print(f"1-In p1.py:__name__ =={__name__}")
if __name__ == '__main__':
    main()

直接运行p1.py,输出如下👇,可见此时p1.py文件的__name__ 为’__main__':
在这里插入图片描述
假设p2.py内容如下,import了p1.py的main(),但是后续并没有调用:

from p1 import main

print("2-This is p2.py file~")
def main():
    print("2-This is main() function in p2.py~")
print(f"1-In p2.py:__name__ =={__name__}")
if __name__ == '__main__':
    main()

运行p2.py的输出如下👇:
在这里插入图片描述
分析可知p1.py中的if __name__ == '__main__':的内容没有执行——即p1.py中的main()函数没有被调用,没有输出那一行。因此p2.py中通过import引用p1.py,运行p2.py时,p1.py中的__name__ ≠ '__main__'而是__name__ = 'p1'。 另外可见输出结果的第二行,直接输出了p1.py文件的__name__。

import到底导入了什么?

一个python文件中定义的类、函数、变量等可以在其他python文件中通过import引入并使用,以实现代码复用。关于import的具体用法(即当一个项目文件夹下很多文件夹,同级、不同级python文件间的引用,以及绝对引用和相对引用)可以参考这个博客👉python中import的用法

这里我想说的是,p2.py引用了p1.py中的某一个函数(比如main()),那仅仅只是main()函数会被解析吗? 实际并不是这样的! 运行p2.py,解析到from p1 import main时,除了找到p1.py的main()相关代码解析以外,还会解析p1.py中的顶层代码——比如全局变量、顶层的print语句等等
p1.py和p2.py的内容同上,在p2.py中仅仅一句from p1 import main与p1相关,且后续并没有调用p1.main(),但为什么输出中第1行和第2行是p1中的内容? 因为p1.py中顶格写的两行print是顶层代码/全局代码,import的时候会解析执行。

argparse解析命令行参数的过程

我们在代码中会定义一些变量,以便在需要的时候更改变量的值,这是一种方式。还有一种更灵活的方式,不用在每次执行时更改变量值(更改代码),而是通过命令行输入参数/变量及其对应的值,此时需要命令行参数解析工具。
python中通过命令行(即输入指令)输入的参数或者值,会存在sys.argv中。测试代码如下👇:

import sys
for i in sys.argv:
     print(i)

在终端中输入—python p1.py arg1 arg2 arg3 arg4,输出为—p1.py arg1 arg2 arg3 arg4,即第一个是文件本身,之后就对应命令行输入的参数。

python内置的argparse模块,可以定义/添加需要的命令行参数,然后从 sys.argv 解析出这些参数,使用过程分成三步:

  • ①创建一个解析器——argparse.ArgumentParser(description=‘……’)
import argparse
# 创建一个解析实例
parser = argparse.ArgumentParser(description='Declare some parameters')
  • ②添加参数——parser.add_argument()
parser.add_argument('--gpu-index', default = 4, type= int, help='The index of gpu') 
parser.add_argument('--model', default = 'resnet18', type= str, help='The type of model') 

这里添加了两个参数,参数名称分别是gpu-indexmodel,其前缀--指明这是一个可选参数。add_argument()可以添加两类参数:位置参数【参数名称前不需要添加-或者–,如’para1’】,命令行输入时不需要输入参数名称,直接输入需要传入的值即可,argparse从命令行解析这类参数时,是顺序解析的,即先添加的未知参数先解析赋值;可选参数【参数名称前有--或者-,只有一个短横线的是缩写/简写】,argparse解析命令行参数时根据参数名称解析,命令行中参数的顺序与参数添加的顺序无关。

import argparse
parse = argparse.ArgumentParser()
# 添加三个参数,par1和par2是位置参数,命令行不需要输入参数名称
# --name是可选参数,命令行必须输入名称
parse.add_argument('par1',type= int)
parse.add_argument('--name',type= str)
parse.add_argument('par2',type= int)
# 参数解析
args = parse.parse_args()
# 输出各个参数名称及值
for arg in vars(args):  
    print(f"{arg}: {getattr(args, arg)}")  

python p1.py 1 --name 'test' 2和用python p1.py 3 4 --name 'tests'运行的结果分别如下:
在这里插入图片描述 ___________________ 在这里插入图片描述
可见对于位置参数是按顺序解析的,即先输入的值对应先添加的参数,但是可选参数的值是根据参数名称解析的。

  • ③解析参数—parse_args()
args = parse.parse_args()

ArgumentParser 通过 parse_args() 方法解析参数。它将检查命令行,把每个参数转换为适当的类型然后调用相应的操作。在大多数情况下,这意味着一个简单的 Namespace 对象将从命令行解析出的属性构建

argparse使用add_argument()函数添加参数时,除参数名称name or flags外还有很多可选的参数(参考👉add_argumenr()):
在这里插入图片描述

Debug—案例分析

事情是这样的,我有一个main_train.py,大致内容如下:

import torch
import torch.nn as nn
import torch.utils.data as Data
from torchvision import datasets, transforms
import numpy as np
# 添加参数
import argparse
parser = argparse.ArgumentParser()  
parser.add_argument('--gpu-index', default = 4, type= int, help='The index of gpu') 
parser.add_argument('--model', default = 'resnet18', type= str, help='The type of model') 
args = parser.parse_args()
# 输出参数及值
for arg in vars(args):  
    print(f"{arg}: {getattr(args, arg)}")  
# 准备GPU
gpu_idx = args.gpu_index
if torch.cuda.is_available():
    device = torch.device(f"cuda:{gpu_idx}")
else:
    device = torch.device('cpu')

def load_cifar10():   
   	pass

def correctness(model, dataset, device):
	pass

def load_model(model, device):
	pass
# 其他内容略

还有在同一目录下的main_forget.py,大致内容如下👇,主要就是从main_train.py中import了里面的三个函数:【注意main_train.py中只添加了2个参数,main_forget.py中添加了7个参数】

import copy
import torch
import torch.nn as nn
import torch.utils.data as Data
from torchvision import datasets, transforms
# 添加参数
import argparse
parser = argparse.ArgumentParser() 
parser.add_argument('--gpu-index', default = 0, type= int, help='The index of gpu') 
parser.add_argument('--model', default = 'resnet18', type= str, help='The type of model') 
parser.add_argument('--batch-size', default = 256, type= int, help='The batchsize of retain and test dataloader') 
parser.add_argument('--seed', default = 200, type= int, help='The seed to set random function') 
parser.add_argument('--rate', default = 0.1, type= float, help='The proportion of forgotten data') 
parser.add_argument('--unlearn', default = 'wfisher', type= str, help='the specific methods of data unlearning',
                    choices=['wfisher','fisher_new','GA','FT','retrain']) 
parser.add_argument("--alpha", default=0.2, type=float, help="unlearn noise")
# 解析参数
args = parser.parse_args()
# 输出参数
for arg in vars(args):  
    print(f"{arg}: {getattr(args, arg)}")  
# !!!引入main_train.py中的三个函数
from main_train import load_cifar10, load_model, correctness

#…………省略

现在我们运行python main_forget.py --model 'resnet34' --gpu-index 3是ok的,输出内容如下:
在这里插入图片描述
分析输出内容:第一个框对应main_forget.py文件输出的argparse添加的参数,并且model和gpu-index的值为命令行中输入的;但是后面的输出是什么???——后面框对应的是main_train.py中的顶层代码!并且main_train.py中的两个参数值也更改为了命令行输入的参数值。

但是当我们输入python main_forget.py --unlearn 'FT' --seed 100时,会发生什么呢?👇
在这里插入图片描述
第一个框依旧对应main_forget.py中的7个变量,此时unlearn和seed更改为命令行输入的值;但是后面却提示error: unrecognized arguments,这是因为从main_train.py引入三个函数的同时,还会额外解析执行其顶层代码,main_train.py中argparse相关部分的代码是顶层代码,因此会再一次创建一个argparse对象,在解析到main_train.py中的args = parser.parse_args()时又会去解析匹配命令行的参数,但是main_train.py的argparse解析器只有两个参数——model和gpu-index,命令行输入的却是——unlearn和seed,自然是无法匹配的,因此就会出现解析错误。

上述例子告诉我们,在写一个项目的时候,一些需要多次使用的基础功能性函数单独写在一个文件中,比如utils.py;顶层创建了argparse解析器的文件不要随便引用,或者单独写一个argparse解析器添加参数的代码文件。总之是要注意代码规范……🥲

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GitLab 中国发行版如何设置镜像拉取策略?

最近在用极狐GitLab(极狐GitLab 可以理解为 GitLab 在中国的发行版) CI/CD 的时候遇到一个问题:CI/CD 中有一个 stage 需要拉取 dockerhub 上的镜像,但是由于 dockerhub 在国内的访问不是很顺畅,经常发生 timeout 的情…

pytest框架的基本使用

1. 测试框架的作用 测试框架不关系用例的内容 它关心的是:用例编排和结果收集 2. pytest框架的特点 1. 适用于python语言 2. 用法符合python风格 3. 有丰富的生态 3. 安装pytest框架 1. 新建一个项目 2. 在项目终端窗口输入如下命令,用于安装py…

危险!这3本期刊陆续被三大数据库剔除!2024年EI期刊目录首次更新!

【SciencePub学术】2024年1月1日,爱思唯尔更新了EI Compendex收录期刊目录。 继上次EI期刊目录更新之后,本次1月更新共有3本期刊发生变动: 其中,有3本期刊停止收录(DISCONTINUED),连续出版/核心…

如何使用Docker部署WBO白板并实现公网地址远程访问

本文主要是如何使用Docker部署WBO白板并实现公网地址远程访问的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 🌄每日一句&am…

MySql语句中的ON DUPLICATE KEY UPDATE使用详解

目录 一:主键索引,唯一索引和普通索引的关系1. 主键索引2. 唯一索引:3. 普通索引:1:ON DUPLICATE KEY UPDATE功能介绍:2:ON DUPLICATE KEY UPDATE测试样例总结: 执行以下实验进行分析…

苹果m1、m2安装blender GIS,解决not Imageio 报错

blender-GIS 能够在地图上生成地形,如下图所示: 使用blenderGIS过程中会有 imageio 找不到的情况, 网上的 imageio 用在苹果电脑的M1、M2芯片上好像还是没有出图,似乎这个 imageio 这个已经是好几年前的代码,没能适配…

100天精通鸿蒙从入门到跳槽——第20天:ArkTS装饰器@Link双向数据绑定

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通Golang》 — Go语言学习之旅!《100天精通鸿蒙》 — 从Web/安卓到鸿蒙大师!100天…

C语言——O / 动态内存管理

一、为什么要有动态内存分配 我们已经掌握的内存开辟⽅式有: int val 20;//在栈空间上开辟四个字节 char arr[10] {0};//在栈空间上开辟10个字节的连续空间 但是上述的开辟空间的⽅式有两个特点: • 空间开辟⼤⼩是固定的。 • 数组在申明的时候&am…

头戴式耳机推荐,适合学生党入手的平价头戴式耳机型号品牌推荐

市面上的头戴式耳机品牌繁多,价格各异,如何选择一款性价比高、适合自己的头戴式耳机呢?作为一个使用过不下十几款的头戴式耳机的大户,接下来我就根据我自己的经验为大家推荐一些平价好用的头戴式耳机,让学生党在预算有…

亚信安慧AntDB:AntDB-M元数据锁(六)

5.4.2 慢路径(slow path) 对于obtrusive锁,以及当前申请unobtrusive锁,而锁对象下已经持有obtrusive锁时,需要进入慢路径申请锁,即先对锁对象下的读写锁加写锁。在当前锁对象首次进入慢路径时,…

iOS 自动打包如何配置配置打包证书和profile provision文件

Jenkins 打包相关问题记录 打包失败截图: 1、证书找不到 NO certificate matching ‘ ‘ for ‘ ’ code singing is required …. D791BAD1-390A-4587-A35C-A743A3D88D52.png 由于更新过证书配置,导致新证书没有导入到Jenkins中。 配置步骤&#xf…

【AI视野·今日Robot 机器人论文速览 第七十六期】Fri, 12 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Fri, 12 Jan 2024 Totally 12 papers 👉上期速览✈更多精彩请移步主页 Daily Robotics Papers Topology-Driven Parallel Trajectory Optimization in Dynamic Environments Authors Oscar de Groot, Laura Ferranti, Dari…

Hadoop3.x基础(1)

来源:B站尚硅谷 这里写目录标题 大数据概论大数据概念大数据特点(4V)大数据应用场景 Hadoop概述Hadoop是什么Hadoop发展历史(了解)Hadoop三大发行版本(了解)Hadoop优势(4高)Hadoop组成&#xf…

MMCLMC公差计算.exe

一、概要 软件及完整代码请戳这里:MMC&LMC公差计算软件及代码 图1 软件操作界面 本软件功能主要是根据实际应用选择MMR或者LMR原则,输入基本尺寸、形位公差尺寸和实际测量尺寸,即可计算出对应的公差值。以孔的MMR为例见如图2、3&#xf…

SpringCloud-高级篇(十六)

前面学习了Lua的语法,就可以在nginx去做编程,去实现nginx类里面的业务,查询Redis,查询tomcat等 ,业务逻辑的编写依赖于其他组件,这些组件会用到OpenResty的工具去实现 (1)安装OpenRe…

不熟悉现货白银的震荡行情?你可以试着这样理解

在现货白银交易中,投资者很不想碰到震荡行情,因为震荡行情说明市场没有明确的趋势,而是倾向于横向波动,因此没有潜在风险较低且潜在盈利较大的顺势交易机会。可不幸的是,在市场中大部分时间市场还是会倾向横向震荡&…

WhatsApp首次营销模板怎么写?WhatsApp营销效果怎么样?

近年来,随着社交媒体的飞速发展,WhatsApp作为一种全球通用的即时通讯应用程序,在营销领域备受重视。很多企业开始利用WhatsApp这一平台与客户进行沟通和营销推广活动。本文将探讨WhatsApp首次营销模板如何编写以及其所带来的效果。 首先&…

MG7050VAN 基于声表的差分多输出 晶体振荡器(LVDS)

MG7050VAN的LVDS输出是一款差分多输出晶体振荡器,具有极低的抖动和超强的稳定性。该振荡器适用于多种应用场景,如服务器、存储器和网络仪器等。作为一款高端的LVDS输出设备,该振荡器在输出性能上具有明显优势。其超低抖动水平可以达到0.3ps M…

【机器学习】强化学习(七)-策略梯度算法-REINFORCE 训练月球着陆器代理(智能体)...

概 述 月球着陆器代理是一个模拟飞行器在月球表面着陆的环境,它有八个连续的状态变量,分别是水平坐标、垂直坐标、水平速度、垂直速度、角度、角速度、腿1触地、腿2触地。它有四个离散的动作,分别是什么都不做、发动左方向引擎、发动主引擎、…

情人节爆品出现!单周GMV暴涨6成,直冲20K美金,节庆用品赛道迎来“爆单潮”!

2024新年钟声已经敲响,一大波节日爆品正在疯狂涌现,而这只是一个开始。 开年首月电商流量一波接一波来袭,下一个“消费大节”已经在来的路上!——情人节。 节日营销热点抢量,宜早不宜晚。商家们纷纷开始上新节庆相关…