【python】argparse解析参数的过程

python基础知识

  • python文件解析
  • `if __name__ == '__main__'的作用
  • import到底导入了什么?
  • argparse解析命令行参数的过程

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文件(比如p2.py)中通过import机制引用另一个文件(比如p1.py)的部分代码,比如定义的一个class、function等等,就能在p2.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,输入如下:
在这里插入图片描述
假设p2.py内容如下,import了p1.py的内容:

from p1 import mainprint("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中importp1.py,p1.py中的\_\_name\_\_ ≠ '\_\_main\_\_'而是\_\_name\_\_ ≠ 'p1'

import到底导入了什么?

一个python文件中定义的class、function可以在其他python文件中通过import引入并使用,关于import的具体用法(即在一个项目中很多文件夹,同级、不同级文件间的引用,以及绝对路劲的引用和相对路径的引用)可以参考这个博客👉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(),但是输出中第一/第二行还是会有p1中的内容? 因为p1.py中顶格写的两行print是顶层代码/全局代码,import的时候会解析执行。

argparse解析命令行参数的过程

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

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

那么输出就是: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():   passdef correctness(model, dataset, device):passdef load_model(model, device):pass
# 其他内容略

还有在同一目录下的main_forget.py,大致内容如下👇,主要就是从main_train.py中国import了里面的三个函数:

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#…………省略

可以看到,main_train.py中只添加了2个参数,main_forget.py中添加了7个参数。现在我们运行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引入三个函数的同时,还会额外解析执行其顶层代码,即会再一次创建一个argparse对象,在解析到args = parser.parse_args()时又会去解析匹配命令行的参数,但是main_train.py的argparse解析器只有两个参数——model和gpu-index,命令行输入的却是——unlearn和seed,自然时无法匹配的,因此就会出现解析错误。

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

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

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

相关文章

【C++杂货铺】详解类和对象 [上]

博主:代码菌-CSDN博客 专栏:C杂货铺_代码菌的博客-CSDN博客 目录 🌈前言🌈 📁 面向对象语言的特性 📁 类 📂 概念 📂 定义 📁 访问限定符 📂分类 &#x…

CMake 完整入门教程(一)

1 前言 每一次学习新东西都是很有乐趣的,虽然刚开始会花费时间用来学习,但是实践证明,虽然学习新东西可能会花费一些时间,但是它们带来的好处会远远超过这些花费的时间。学习新东西是值得的,也是很有乐趣的。 网络上…

【K8S 云原生】K8S的图形化工具——Rancher

目录 一、rancher概述 1、rancher概念 2、rancher和K8S的区别: 二、实验 1、安装部署 2、给集群添加监控: 3、创建命名空间: 4、创建deployment: 5、创建service: 6、创建ingress: 7、创建hpa 8…

基于高精度YOLOv8开发构建公共场景下行人人员姿态估计分析识别系统

姿态估计(PoseEstimation)在我们前面的相关项目中涉及到的并不多,CV数据场景下主要还是以目标检测、图像识别和分割居多,最近正好项目中在使用YOLO系列最新的模型开发项目,就想着抽时间基于YOLOv8也开发构建实现人体姿…

[UI5 常用控件] 02.Title,Link,Label

文章目录 前言1. Title1.1 结合Panel1.2 结合Table1.3 Title里嵌套Link 2. Link3. Label3.1 普通用法3.2 在Form里使用 前言 本章节记录常用控件Title,Link,Label。 其路径分别是: sap.m.Titlesap.m.Linksap.m.Label 1. Title Title可以结合其他控件一起使用 1.…

总结红包雨项目的所有代码,包括添加图片,分享按钮,红包雨,用户是否有抽奖逻辑判断

整体实现效果: 需要用的图片: html: <body><div id"app"><!-- <div class"share-box"><img src"./share_box.png" alt"share-button"></div> --><!-- img图片 --><div class"gif-…

JVM基础知识汇总篇

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一

随着 OpenAI 在多模态方面的最新进展&#xff0c;想象一下将这种能力与视觉理解相结合。 现在&#xff0c;您可以在 Streamlit 应用程序中使用 GPT-4 和 Vision&#xff0c;以&#xff1a; 从草图和静态图像构建 Streamlit 应用程序。帮助你优化应用的用户体验&#xff0c;包…

《合成孔径雷达成像算法与实现》Figure5.18

clc clear close all距离向参数 R_eta_c 20e3; % 景中心斜距 Tr 25e-6; % 发射脉冲时宽 Kr 0.25e12; % 距离向调频率 Fr 7.5e6; % 距离向采样率 Nrg 256; % 距离线采样点数 Bw abs(Kr*Tr); …

.NET绿色开源一键自动化下载、安装、激活Office的利器

前言 今天分享一款.NET开源、绿色、安全、无毒的支持一键自动化下载、安装、激活Microsoft Office的利器&#xff1a;LKY_OfficeTools。 工具介绍 一键自动化下载、安装、激活 Microsoft Office 的利器。绿色、开源、安全、无毒。 目前包含的功能&#xff1a; 一键快速下载、…

【机器学习300问】16、逻辑回归模型实现分类的原理?

在上一篇文章中&#xff0c;我初步介绍了什么是逻辑回归模型&#xff0c;从它能解决什么问题开始介绍&#xff0c;并讲到了它长什么样子的。如果有需要的小伙伴可以回顾一下&#xff0c;链接我放在下面啦&#xff1a; 【机器学习300问】15、什么是…

C#,计算几何,二维贝塞尔拟合曲线(Bézier Curve)参数点的计算代码

Pierre Bzier Bzier 算法用于曲线的拟合与插值。 插值是一个或一组函数计算的数值完全经过给定的点。 拟合是一个或一组函数计算的数值尽量路过给定的点。 这里给出 二维 Bzier 曲线拟合的参数点计算代码。 区别于另外一种读音接近的贝塞耳插值算法&#xff08;Bessels int…

【CAD全套教程】第1阶段 CAD软件教程 002+003基础界面设置

002基础界面设置 1.切换界面至AutoCAD经典界面 方式一&#xff1a;任务栏点击后直接选择 方式二&#xff1a;右下角点击齿轮图标&#xff08;切换工作空间&#xff09;后直接选择 界面图 2.AutoCAD常用命令 工具栏右键单击&#xff0c;选择AutoCAD 3.命令提示行 最下方&#xf…

【Docker】实现JMeter分布式压测

一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试。如本网站所示&#xff0c;一个JMeter实例将能够控制许多其他的远程JMeter实例&#xff0c;并对你的应用程序产生更大的负载。JMeter使用Java RMI[远程方法调用]来与分布式网络中的对象进行交互。JMeter主站…

【前端web入门第二天】01 html语法实现列表与表格_合并单元格

html语法实现列表与表格 文章目录: 1.列表 1.1 无序列表1.2 有序列表1.3 定义列表 2.表格 2.1 表格基本结构2.2 表格结构标签2.3 合并单元格 写在最前,第二天学习目标: 列表 表格 表单 元素为嵌套关系 1.列表 作用:布局内容排列整齐的区域。 列表分类:无序列表、有序列表…

数字IC实践项目(8)—CNN加速器(ASIC_Flow;付费项目补充)

数字IC实践项目&#xff08;8&#xff09;—CNN加速器&#xff08;ASIC_Flow&#xff1b;付费项目补充&#xff09; 更新说明项目整体框图神经网络框图File tree 项目简介和学习目的软件环境要求 Area、QOR、Power&Timing报告Area & QORTiming & Power 总结 更新说…

【C++】类与对象(一)

前言 类与对象&#xff08;一&#xff09; 文章目录 一、面向对象和面向过程的对比二、类的引入2.1 C中的结构体2.2 类2.3 类定义方法2.4 修饰限定符2.5 封装2.6 类的实例化2.7 类对象的大小 三、this指针3.1 this 指针的使用 一、面向对象和面向过程的对比 面向过程编程是将程…

GoJS—交互式图表开发的神器(海量案例)

一、GoJS是什么&#xff1a; GoJS是一个用于创建交互式可视化图表和图形的JavaScript库。它提供了丰富的功能和工具&#xff0c;使开发人员能够轻松地构建各种类型的图表&#xff0c;包括流程图、组织结构图、网络拓扑图等。GoJS具有灵活的布局和样式设置&#xff0c;可以通过简…

Python中Numba库装饰器

一、运行速度是Python天生的短板 1.1 编译型语言&#xff1a;C 对于编译型语言&#xff0c;开发完成以后需要将所有的源代码都转换成可执行程序&#xff0c;比如 Windows 下的.exe文件&#xff0c;可执行程序里面包含的就是机器码。只要我们拥有可执行程序&#xff0c;就可以随…

基于STM32的智能手环设计与实现

需要原理图工程&#xff0c;源码&#xff0c;PCB工程的朋友收藏&#xff0c;这篇文章关注我&#xff0c;私我吧&#xff01;&#xff01;&#xff01; 基于STM32的智能手环设计与实现 摘要一、研究背景及意义二、实现功能三、系统方案设计系统方案设计框图3.1 单片机芯片选择3…