zoukankan      html  css  js  c++  java
  • python中关于传递参数模块argprase的一些小坑

    今天在写代码的时候遇到了一个关于parser的一些小坑,记录在此备用。

    我们知道在python中可以用argprase来传递一些参数给代码执行,来看下面的例子,假设现在有一个test文件夹,下面有3个python文件,分别用a.py;b.py;c.py来表示,目录树如下。

     每一个的初始代码为一个简单的print函数。

    1 #a.py
    2 def out_a():
    3     print("I am a.py")
    4 
    5 
    6 if __name__ == '__main__':
    7     out_a()
    1 #b.py
    2 def out_b():
    3     print("I am b.py")
    4 
    5 
    6 if __name__ == '__main__':
    7     out_b()
    1 #c.py
    2 def out_c():
    3     print("I am c.py")
    4 
    5 
    6 if __name__ == '__main__':
    7     out_c()

    现在在a.py中引入模块argprase,并定义一些简单的参数,代码如下

     1 import argparse
     2 parser = argparse.ArgumentParser()
     3 parser.add_argument('--first_parameter', default='first')
     4 parser.add_argument('--second_parameter', default='second')
     5 parser.add_argument('--third_flag', action='store_true')
     6 args = parser.parse_args()
     7 
     8 
     9 def out_a():
    10     print("I am a.py")
    11 
    12 
    13 if __name__ == '__main__':
    14     out_a()

    这里面简单说一下第3个参数,这也是我今天想记录文章的原因,这个参数是argparse里面提供的开关布尔选项,actions记录的是一个动作,意味着在调用这个函数的时候,如果在命令行添加这个参数,则该参数为True,如果不添加这个参数,则该参数为False,归纳起来为如下的两个图。

    这个是没有指定第3个参数的情况

     

    这个是指定第3个参数的情况

    对于这种开关布尔选项更为详细的介绍,可以参考知乎问题:Argparse中action的可选参数store_true,store_false到底是什么意思?

    到目前为止没有出现问题,接下来,我希望b.py也使用参数,并且还希望使用a.py里面的函数,因此我对b.py进行如下修改。

     1 from a import out_a
     2 import argparse
     3 parser = argparse.ArgumentParser()
     4 parser.add_argument('--fourth_parameter', default='fourth')
     5 parser.add_argument('--fifth_parameter', default='fifth')
     6 parser.add_argument('--sixth_flag', action='store_true')
     7 args = parser.parse_args()
     8 
     9 
    10 def out_b():
    11     print("I am b.py")
    12 
    13 
    14 if __name__ == '__main__':
    15     out_b()
    16     out_a()

    然后同样的,我们分别用两种方式来测试b.py,效果如下。

    这个是不使用参数的情况 

    这个是使用参数的情况

    可以看到报错了,当时我看到这里的时候想了很久,排除了拼写错误的情况以后,观察这里面的输出,发现看到的是a.py当中的3个参数,而不是b.py当中设置的参数,于是我将a.py和b.py的参数表打印出来,看到这样子的结果。

    输出两个python文件的参数表

    可以发现尽管我使用的是 from a import out_a ,但依然引入了a.py当中的参数表,并且后引入的b.py的参数表没有办法覆盖掉。下面在c.py中同样引入3个参数,然后引入b.py的方法,代码如下:

     1 from b import out_b
     2 import argparse
     3 parser = argparse.ArgumentParser()
     4 parser.add_argument('--seventh_parameter', default='seventh')
     5 parser.add_argument('--eighth_parameter', default='eighth')
     6 parser.add_argument('--ninth_flag', action='store_true')
     7 args = parser.parse_args()
     8 print(args)
     9 
    10 def out_c():
    11     print("I am c.py")
    12 
    13 
    14 if __name__ == '__main__':
    15     out_c()
    16     out_b()

    效果如下

    不使用任何参数调用c.py

    看到有3个参数列表输出就知道c.py的参数也是无效的了,验证一下。

    使用参数调用c.py

    解决方案:

    其实只需要将所有的参数表放到同一个文件里面就可以了,比如utils.py,由于这里是同一个文件夹下的3个文件,在import调用的时候就只需要初始化一次所有参数就可以使用了,有点类似于C语言当中的全局变量,因为这个东西排查了一个下午,也是有点恼火了。

  • 相关阅读:
    记laravel项目,本地环境PHP7.1,线上PHP版本7.2,报错each函数废弃问题
    [教程] 《Mysql 实战 45 讲》
    PHP递归求和计算1加到n的和
    SSL原理
    PHP之抽象类与接口
    iOS调试之挂起线程
    iOS之Starfield
    iOS之透视效果
    CSS之框模型
    HTTP之CacheControl
  • 原文地址:https://www.cnblogs.com/jcchan/p/12006483.html
Copyright © 2011-2022 走看看