精华内容
下载资源
问答
  • Click 是 Python Web 开发框架 Flask的作者开发的一个库,用于快速...作者:funhacks原文:https://funhacks.net/2016/12/20/click/Click 是 Python 写的一个第三方模块,用于快速创建命令行。我们知道,Python 内...
    1a655823dd6079d2797719aef8e6dc12.png

    Click 是 Python Web 开发框架 Flask的作者开发的一个库,用于快速创建命令行,目前已经整合到了最新版的 Flask 当中。Click 功能强大,使用也比较简单,值得大家学习使用。

    作者:funhacks

    原文:https://funhacks.net/2016/12/20/click/

    Click 是用 Python 写的一个第三方模块,用于快速创建命令行。我们知道,Python 内置了一个 Argparse 的标准库用于创建命令行,但使用起来有些繁琐,Click 相比于 Argparse,就好比 requests 相比于 urllib。

    快速使用

    Click 的使用大致有两个步骤:

    使用 @click.command 装饰一个函数,使之成为命令行接口; 使用 @click.option 等装饰函数,为其添加命令行选项等。 它的一种典型使用形式如下:

    importclick

    @click.command

    @click.option('--param', default=default_value, help='description')

    deffunc(param):

    pass

    下面,让我们看一下官方文档的入门例子:

    importclick

    @click.command

    @click.option('--count', default=1, help='Number of greetings.')

    @click.option('--name', prompt='Your name', help='The person to greet.')

    defhello(count, name):

    """Simple program that greets NAME for a total of COUNT times."""

    forxinrange(count):

    click.echo('Hello %s!' % name)

    if__name__ == '__main__':

    hello

    在上面的例子中,函数 hello 有两个参数:count 和 name,它们的值从命令行中获取。

    • @click.command 使函数 hello 成为命令行接口;

    • @click.option 的第一个参数指定了命令行选项的名称,可以看到,count 的默认值是 1;

    • 使用 click.echo 进行输出是为了获得更好的兼容性,因为 print 在 Python2 和 Python3 的用法有些差别。

    看看执行情况:

    $ python hello.py

    Your name: Ethan # 这里会显示 'Your name: '(对应代码中的 prompt),接受用户输入

    Hello Ethan!

    $ python hello.py --help # click 帮我们自动生成了 `--help` 用法

    Usage: hello.py [OPTIONS]

    Simple program that greets NAME fora total of COUNT times.

    Options:

    --count INTEGER Number of greetings.

    --name TEXT The person to greet.

    --help Show thismessageandexit.

    $ python hello.py --count 3--name Ethan # 指定 count 和 name 的值

    Hello Ethan!

    Hello Ethan!

    Hello Ethan!

    $ python hello.py --count=3--name=Ethan # 也可以使用 `=`,和上面等价

    Hello Ethan!

    Hello Ethan!

    Hello Ethan!

    $ python hello.py --name=Ethan # 没有指定 count,默认值是 1

    Hello Ethan!

    click.option

    option 最基本的用法就是通过指定命令行选项的名称,从命令行读取参数值,再将其传递给函数。在上面的例子,我们看到,除了设置命令行选项的名称,我们还会指定默认值,help 说明等,option 常用的设置参数如下:

    • default: 设置命令行参数的默认值

    • help: 参数说明

    • type: 参数类型,可以是 string, int, float 等

    • prompt: 当在命令行中没有输入相应的参数时,会根据 prompt 提示用户输入

    • nargs: 指定命令行参数接收的值的个数

    下面,我们再看看相关的例子。

    指定 type

    我们可以使用 type 来指定参数类型:

    importclick

    @click.command

    @click.option('--rate', type=float, help='rate') # 指定 rate 是 float 类型

    defshow(rate):

    click.echo('rate: %s' % rate)

    if__name__ == '__main__':

    show

    执行情况:

    $ python click_type.py --rate 1

    rate: 1.0

    $ python click_type.py --rate 0.66

    rate: 0.66

    可选值

    在某些情况下,一个参数的值只能是某些可选的值,如果用户输入了其他值,我们应该提示用户输入正确的值。在这种情况下,我们可以通过 click.Choice 来限定:

    importclick

    @click.command

    @click.option('--gender', type=click.Choice(['man', 'woman'])) # 限定值

    defchoose(gender):

    click.echo('gender: %s' % gender)

    if__name__ == '__main__':

    choose

    执行情况:

    $ python click_choice.py --gender boy

    Usage: click_choice.py [OPTIONS]

    Error: Invalid value for"--gender": invalid choice: boy. (choosefromman, woman)

    $ python click_choice.py --gender man

    gender: man

    多值参数

    有时,一个参数需要接收多个值。option 支持设置固定长度的参数值,通过 nargs 指定。

    看看例子就明白了:

    importclick

    @click.command

    @click.option('--center', nargs=2, type=float, help='center of the circle')

    @click.option('--radius', type=float, help='radius of the circle')

    defcircle(center, radius):

    click.echo('center: %s, radius: %s' % (center, radius))

    if__name__ == '__main__':

    circle

    在上面的例子中,option 指定了两个参数:center 和 radius,其中,center 表示二维平面上一个圆的圆心坐标,接收两个值,以元组的形式将值传递给函数,而 radius 表示圆的半径。

    执行情况:

    $ python click_multi_values.py --center 34--radius10

    center: (3.0,4.0), radius:10.0

    $ python click_multi_values.py --center 345--radius10

    Usage: click_multi_values.py [OPTIONS]

    Error: Got unexpected extra argument (5)

    输入密码

    有时,在输入密码的时候,我们希望能隐藏显示。option 提供了两个参数来设置密码的输入:hideinput 和 confirmationpromt,其中,hideinput 用于隐藏输入,confirmationpromt 用于重复输入。

    看看例子:

    importclick

    @click.command

    @click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True)

    definput_password(password):

    click.echo('password: %s' % password)

    if__name__ == '__main__':

    input_password

    执行情况:

    $ python click_password.py

    Password: # 不会显示密码

    Repeat forconfirmation: # 重复一遍

    password: 666666

    由于上面的写法有点繁琐,click 也提供了一种快捷的方式,通过使用 @click.password_option,上面的代码可以简写成:

    importclick

    @click.command

    @click.password_option

    definput_password(password):

    click.echo('password: %s' % password)

    if__name__ == '__main__':

    input_password

    改变命令行程序的执行

    有些参数会改变命令行程序的执行,比如在终端输入 python 是进入 python 控制台,而输入 python --version 是打印 python 版本。Click 提供 eager 标识对参数名进行标识,如果输入该参数,则会拦截既定的命令行执行流程,跳转去执行一个回调函数。

    让我们看看例子:

    importclick

    defprint_version(ctx, param, value):

    ifnotvalueorctx.resilient_parsing:

    return

    click.echo('Version 1.0')

    ctx.exit

    @click.command

    @click.option('--version', is_flag=True, callback=print_version,

    expose_value=False, is_eager=True)

    @click.option('--name', default='Ethan', help='name')

    defhello(name):

    click.echo('Hello %s!' % name)

    if__name__ == '__main__':

    hello

    其中:

    • is_eager=True 表明该命令行选项优先级高于其他选项;

    • expose_value=False 表示如果没有输入该命令行选项,会执行既定的命令行流程;

    • callback 指定了输入该命令行选项时,要跳转执行的函数;

    执行情况:

    $ python click_eager.py

    Hello Ethan!

    $ python click_eager.py --version # 拦截既定的命令行执行流程

    Version 1.0

    $ python click_eager.py --name Michael

    Hello Michael!

    $ python click_eager.py --version --name Ethan # 忽略 name 选项

    Version 1.0

    click.argument

    我们除了使用 @click.option 来添加可选参数,还会经常使用 @click.argument 来添加固定参数。它的使用和 option 类似,但支持的功能比 option 少。

    入门使用

    下面是一个简单的例子:

    importclick

    @click.command

    @click.argument('coordinates')

    defshow(coordinates):

    click.echo('coordinates: %s' % coordinates)

    if__name__ == '__main__':

    show

    看看执行情况:

    $ python click_argument.py # 错误,缺少参数 coordinates

    Usage: click_argument.py [OPTIONS] COORDINATES

    Error: Missing argument "coordinates".

    $ python click_argument.py --help # argument 指定的参数在 help 中没有显示

    Usage: click_argument.py [OPTIONS] COORDINATES

    Options:

    --help Show thismessageandexit.

    $ python click_argument.py --coordinates 10# 错误用法,这是 option 参数的用法

    Error: nosuch option: --coordinates

    $ python click_argument.py 10# 正确,直接输入值即可

    coordinates: 10

    多个 argument

    我们再来看看多个 argument 的例子:

    importclick

    @click.command

    @click.argument('x')

    @click.argument('y')

    @click.argument('z')

    defshow(x, y, z):

    click.echo('x: %s, y: %s, z:%s' % (x, y, z))

    if__name__ == '__main__':

    show

    执行情况:

    $ python click_argument.py 102030

    x: 10, y:20, z:30

    $ python click_argument.py 10

    Usage: click_argument.py [OPTIONS] X Y Z

    Error: Missing argument "y".

    $ python click_argument.py 1020

    Usage: click_argument.py [OPTIONS] X Y Z

    Error: Missing argument "z".

    $ python click_argument.py 10203040

    Usage: click_argument.py [OPTIONS] X Y Z

    Error: Got unexpected extra argument (40)

    不定参数

    argument 还有另外一种常见的用法,就是接收不定量的参数,让我们看看例子:

    importclick

    @click.command

    @click.argument('src', nargs=-1)

    @click.argument('dst', nargs=1)

    defmove(src, dst):

    click.echo('move %s to %s' % (src, dst))

    if__name__ == '__main__':

    move

    其中,nargs=-1 表明参数 src 接收不定量的参数值,参数值会以 tuple 的形式传入函数。如果 nargs 大于等于 1,表示接收 nargs 个参数值,上面的例子中,dst 接收一个参数值。

    让我们看看执行情况:

    $ python click_argument.py file1 trash # src=('file1',) dst='trash'

    move (u'file1',) to trash

    $ python click_argument.py file1 file2 file3 trash # src=('file1', 'file2', 'file3') dst='trash'

    move (u'file1', u'file2', u'file3') to trash

    彩色输出

    在前面的例子中,我们使用 click.echo 进行输出,如果配合 colorama 这个模块,我们可以使用 click.secho 进行彩色输出,在使用之前,使用 pip 安装 colorama:

    $ pip install colorama

    看看例子:

    importclick

    @click.command

    @click.option('--name', help='The person to greet.')

    defhello(name):

    click.secho('Hello %s!' % name, fg='red', underline=True)

    click.secho('Hello %s!' % name, fg='yellow', bg='black')

    if__name__ == '__main__':

    hello

    其中:

    • fg 表示前景颜色(即字体颜色),可选值有:BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE 等;

    • bg 表示背景颜色,可选值有:BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE 等;

    • underline 表示下划线,可选的样式还有:dim=True,bold=True 等;

    小结

    使用 click.command 装饰一个函数,使其成为命令行接口。 使用 click.option 添加可选参数,支持设置固定长度的参数值。 使用 click.argument 添加固定参数,支持设置不定长度的参数值。

    题图:pexels,CC0 授权。

    展开全文
  • 一、前言在近半年的 Python 命令行旅程中,我们依次学习了 argparse、docopt、click 和 fire 库的特点和用法,逐步了解到 Python 命令行库的设计哲学与演变。 本文作为本次旅程的终点,希望从一个更高的视角对这些库...

    一、前言

    在近半年的 Python 命令行旅程中,我们依次学习了 argparse、docopt、click 和 fire 库的特点和用法,逐步了解到 Python 命令行库的设计哲学与演变。 本文作为本次旅程的终点,希望从一个更高的视角对这些库进行横向对比,总结它们的异同点和使用场景,以期在应对不同场景时能够分析利弊,选择合适的库为己所用。

    本系列文章默认使用 Python 3 作为解释器进行讲解。若你仍在使用 Python 2,请注意两者之间语法和库的使用差异哦~

    这里还要注意:不管你是为了Python就业还是兴趣爱好,记住:项目开发经验永远是核心,如果如果你没有2020最新python入门到高级实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,里面很多新python教程项目,还可以跟老司机交流讨教!

    二、设计理念

    在讨论各个库的设计理念之前,我们先设计一个计算器程序,其实这个例子在 argparse 库的第一篇讲解中出现过,也就是:

    • 命令行程序接受一个位置参数,它能出现多次,且是数字
    • 默认情况下,命令行程序会求出给定的一串数字的最大值
    • 如果指定了选项参数 --sum,那么就会将求出给定的一串数字的和

    希望从各个库实现该例子的代码中能进一步体会它们的设计理念。

    2.1、argparse

    argparse 的设计理念就是提供给你最细粒度的控制,你需要详细地告诉它参数是选项参数还是位置参数、参数值的类型是什么、该参数的处理动作是怎样的。 总之,它就像是一个没有智能分析能力的初代机器人,你需要告诉它明确的信息,它才会根据给定的信息去帮助你做事情。

    以下示例为 argparse 实现的 计算器程序:

    import argparse# 1. 设置解析器parser = argparse.ArgumentParser(description='Calculator Program.')# 2. 定义参数# 添加位置参数 nums,在帮助信息中显示为 num# 其类型为 int,且支持输入多个,且至少需要提供一个parser.add_argument('nums',  metavar='num', type=int, nargs='+',                    help='a num for the accumulator')# 添加选项参数 --sum,该参数被 parser 解析后所对应的属性名为 accumulate# 若不提供 --sum,默认值为 max 函数,否则为 sum 函数parser.add_argument('--sum', dest='accumulate', action='store_const',                    const=sum, default=max,                    help='sum the nums (default: find the max)')# 3. 解析参数args = parser.parse_args(['--sum', '1', '2', '3'])print(args) # 结果:Namespace(accumulate=, nums=[1, 2, 3])# 4. 业务逻辑result = args.accumulate(args.nums)print(result)  # 基于上文的 ['--sum', '1', '2', '3'] 参数,accumulate 为 sum 函数,其结果为 6复制代码

    从上述示例可以看到,我们需要通过 add_argument 很明确地告诉 argparse 参数长什么样:

    • 它是位置参数 nums,还是选项参数 --sum
    • 它的类型是什么,比如 type=int 表示类型是 int
    • 这个参数能重复出现几次,比如 nargs='+' 表示至少提供 1 个
    • 参数的是存什么的,比如 action='store_const' 表示存常量

    然后它才根据给定的这些元信息来解析命令行参数(也就是示例中的 ['--sum', '1', '2', '3'])。

    这是很计算机的思维,虽然冗长,但也带来了灵活性。

    2.2、docopt

    从 argparse 的理念可以看出,它是命令式的。这时候 docopt 另辟蹊径,声明式是不是也可以?一个命令行程序的帮助信息其实已然包含了这个命令行的完整元信息,那不就可以通过定义帮助信息来定义命令行?docopt 就是基于这样的想法去设计的。

    声明式的好处在于只要你掌握了声明式的语法,那么定义命令行的元信息就会很简单。

    以下示例为 docopt 实现的 计算器程序:

    # 1. 定义接口描述/帮助信息"""Calculator Program.Usage:  calculator.py [--sum] ...  calculator.py (-h | --help)Options:  -h --help     Show help.  --sum         Sum the nums (default: find the max)."""from docopt import docopt# 2. 解析命令行arguments = docopt(__doc__, options_first=True, argv=['--sum', '1', '2', '3'])print(arguments) # 结果:{'--help': False, '--sum': True, '': ['1', '2', '3']}# 3. 业务逻辑nums = (int(num) for num in arguments[''])if arguments['--sum']:    result = sum(nums)else:    result = max(nums)print(result) # 基于上文的 ['--sum', '1', '2', '3'] 参数,处理函数为 sum 函数,其结果为 6复制代码

    从上述示例可以看到,我们通过 __doc__ 定义了接口描述,这和 argparse 中 add_argument 是等价的,然后 docopt 便会根据这个元信息把命令行参数转换为一个字典。业务逻辑中就需要对这个字典进行处理。

    对比与 argparse:

    • 对于更为复杂的命令程序,元信息的定义上 docopt 会更加简单
    • 然而在业务逻辑的处理上,由于 argparse 在一些简单参数的处理上会更加便捷(比如示例中的情形),相对来说 docopt 转换为字典后就把所有处理交给业务逻辑的方式会更加复杂

    2.3、click

    命令行程序本质上是定义参数和处理参数,而处理参数的逻辑一定是与所定义的参数有关联的。那可不可以用函数和装饰器来实现处理参数逻辑与定义参数的关联呢?而 click 正好就是以这种使用方式来设计的。

    click 使用装饰器的好处就在于用装饰器优雅的语法将参数定义和处理逻辑整合在一起,从而暗示了路由关系。相比于 argparse 和 docopt 需要自行对解析后的参数来做路由关系,简单了不少。

    以下示例为 click 实现的 计算器程序:

    import sysimport clicksys.argv = ['calculator.py', '--sum', '1', '2', '3']# 2. 定义参数@click.command()@click.argument('nums', nargs=-1, type=int)@click.option('--sum', 'use_sum', is_flag=True, help='sum the nums (default: find the max)')# 1. 业务逻辑def calculator(nums, use_sum):    """Calculator Program."""    print(nums, use_sum) # 输出:(1, 2, 3) True    if use_sum:        result = sum(nums)    else:        result = max(nums)    print(result) # 基于上文的 ['--sum', '1', '2', '3'] 参数,处理函数为 sum 函数,其结果为 6calculator()复制代码

    从上述示例可以看出,参数和对应的处理逻辑非常好地绑定在了一起,看上去就很直观,使得我们可以明确了解参数会怎么处理,这在有大量参数时显得尤为重要,这边是 click 相比于 argparse 和 docopt 最明显的优势。

    此外,click 还内置了很多实用工具和额外能力,比如说 Bash 补全、颜色、分页支持、进度条等诸多实用功能,可谓是如虎添翼。

    2.4、fire

    fire 则是用一种面向广义对象的方式来玩转命令行,这种对象可以是类、函数、字典、列表等,它更加灵活,也更加简单。你都不需要定义参数类型,fire 会根据输入和参数默认值来自动判断,这无疑进一步简化了实现过程。

    以下示例为 click 实现的 计算器程序:

    import sysimport firesys.argv = ['calculator.py', '1', '2', '3', '--sum']builtin_sum = sum# 1. 业务逻辑# sum=False,暗示它是一个选项参数 --sum,不提供的时候为 False# *nums 暗示它是一个能提供任意数量的位置参数def calculator(sum=False, *nums):    """Calculator Program."""    print(sum, nums) # 输出:True (1, 2, 3)    if sum:        result = builtin_sum(nums)    else:        result = max(nums)    print(result) # 基于上文的 ['1', '2', '3', '--sum'] 参数,处理函数为 sum 函数,其结果为 6fire.Fire(calculator)复制代码

    从上述示例可以看出,fire 提供的方式无疑是最简单、并且最 Pythonic 的了。我们只需关注业务逻辑,而命令行参数的定义则和函数参数的定义融为了一体。

    不过,有利自然也有弊,比如 nums 并没有说是什么类型,也就意味着输入字符串'abc'也是合法的,这就意味着一个严格的命令行程序必须在自己的业务逻辑中来对期望的类型进行约束。

    三、横向对比

    最后,我们横向对比下argparse、docopt、click 和 fire 库的各项功能和特点:

    c4ff87d66dd34e78c608828e6ee683c4.png

    Python 的命令行库种类繁多、各具特色。结合上面的总结,可以选择出符合使用场景的库,如果几个库都符合,那么就根据你更偏爱的风格来选择。这些库都很优秀,其背后的思想很是值得我们学习和扩展。

    原文出处:https://www.cnblogs.com/chengxuyuanaa/p/12719696.html

    作者:程序员的人生A

    展开全文
  • 8.2 命令行参数示例(实验) public class Test { public static void main(String[] args){ if(args.length==0){ System.out.println("you don't set command line parameters!"); }else{...

    8.2 命令行参数示例(实验)   

    public class Test {
        public static void main(String[] args){
            if(args.length==0){
                System.out.println("you don't set command line parameters!");
            }else{
                for (int i=0; i<args.length; i++){
                    System.out.println("args[" + i + "] is: " + args[i]);
                }
            } 
        }
    }

    when use eclipse, don't "run as application",directly use "run configurations/run", then add in aguments in program arguments.(当运行eclipse,不要"run as application",而直接用"run configurations/run",然后加上参数在,program arguments.)

    更多请见:http://www.mark-to-win.com/tutorial/java_1_CommandLinePar.html

     

    展开全文
  • 这里写自定义目录标题什么是命令行参数怎么传有什么参数封装过程 什么是命令行参数 首先来说一下什么是命令行参数? 从代码上来讲,命令行参数就是springboot启动类里面那个main方法中的那个args参数,程序启动时...

    什么是命令行参数

    从springboot官网可以知道,通过下面三种方式把一些值当作属性放到spring的上下文中,然后可以再代码中直接读取这些属性的值:

    1. 通过环境变量方式environment variable:
      $ SPRING_APPLICATION_JSON=’{“acme”:{“name”:“test”}}’ java -jar myapp.jar
    2. 通过系统属性system property:
      $ java -Dspring.application.json=’{“acme”:{“name”:“test”}}’ -jar myapp.jar
    3. 通过命令行参数command line argument:
      $ java -jar myapp.jar --spring.application.json=’{“acme”:{“name”:“test”}}’

    我们今天要讲的就是第三种情况,命令行参数。
    首先来说一下什么是命令行参数?
    从代码上来讲,命令行参数就是springboot启动类里面那个main方法中的那个args参数,程序启动时传给那个args变量的东东就是命令行参数。

    怎么传

    那么通过什么方式可以传给他呢?这里介绍两个方式
    方式一:通过命令行,如下:

    java -jar myproject-0.0.1-SNAPSHOT.jar --debug --Mygroup=a,b --filePath=c:/data/1.txt -myargs=2 testNoArg debug=true
    

    方式二:开发是通过idea直接配置,如下:
    在这里插入图片描述
    通过上面两种方式后,–debug --Mygroup=a,b --filePath=c:/data/1.txt -myargs=2 testNoArg debug=true 这部分就会当作参数传给我们springboot启动类的main方法中的args参数了(切记:每项后面加空格)。

    有什么用

    那么启动程序时设置这个参数有什么用呢?我们结合run方法的代码来说明。
    1.通过这些启动时设置参数,可以在启动时向Property中添加属性值。一般我们都是通过application.properties来设置Property的值,然后在程序中可以通过@Value注解来使用。但是如果有些值想在启动时设置,然后通过@Value来获取,那么就可以通过启动参数来设置。所有的这些property都放在springboot官网中说的environment(代码里也是)。springboot启动时关于所有的property还有environment相关的设置,都在SpringApplication这个类的run方法中,源码部分如下:

    public ConfigurableApplicationContext run(String... args) {
    		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);1】
    		ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments)2;
    		prepareContext(context, environment, listeners, applicationArguments, printedBanner);
    		refreshContext(context);3afterRefresh(context, applicationArguments);
    		callRunners(context, applicationArguments);
    		return context;
    	}
    

    【1】中便会把传入的参数进行封装,封装的过程可参考下面的【参数封装过程】。然后得到一个applicationArguments ,这里面就是我们的参数,然后【2】处便把参数的内容放到environment中了,然后environment会放到context中【3】。然后才可以通过@Value获取到了。包括application.properties这些文件中内容都是放到environment中。截了一个向environment中放参数的图,如下
    在这里插入图片描述
    如果不想这些参数放到environment中,使用下面的代码禁用:

    SpringApplication.setAddCommandLineProperties(false)
    

    2.通过将参数封装到ApplicationArguments 后,当我们在代码中可以直接通过注入的方式获取到我们传入给main方法的参数。例子如下:

    @Component
    public class MyBean {
      @Autowired
      public MyBean(ApplicationArguments args) {
        // --Mygroup=a,b --filePath=c:/data/1.txt -myargs=2 testNoArg TestNoarg2=3
        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs(); //option和nonOption的意思文章下面的【参数封装过程】有介绍
        Set<String> optionNames = args.getOptionNames();
        for (String optionName : optionNames) {
          System.out.println("这是传过来的参数[{}]"+optionName);
        }
        String[] sourceArgs = args.getSourceArgs();
        for (String sourceArg : sourceArgs) {
          System.out.println("这是传过来sourceArgs[{}]"+ sourceArg);
        }
      }
    }
    

    参数封装过程

    参数封装的代码层次关系大体如下:
    SpringApplication.run(ApplicationRunner.class, args)
     |-- ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      |-- this.source = new Source(args);
        |-- super(args);【1】
         |-- super(new SimpleCommandLineArgsParser().parse(args));【2】

    CommandLineArgs是一个接口,默认实现类DefaultApplicationArguments。

    【1】处调用的是Source的父类SimpleCommandLinePropertySource的构造方法,如下:

    【1】处调用父类的构造方法如下:
    	public SimpleCommandLinePropertySource(String... args) {
    		super(new SimpleCommandLineArgsParser().parse(args));
    	}
    

    这个构造方法的的参数是一个可变的String类型,所以可以直接把main方法中的参数所有内容都接受到。然后解析这个这些参数内容。解析代码如下:
    以参数 --debug --Mygroup=a,b --filePath=c:/data/1.txt -myargs=2 testNoArg TestNoarg2=3 --debug=true 为例子:

    class SimpleCommandLineArgsParser {
    	public CommandLineArgs parse(String... args) {
    		CommandLineArgs commandLineArgs = new CommandLineArgs();
    		for (String arg : args) {
    		   // 如果-- 开头参数如--filePath=c:/data/1.txt
    			if (arg.startsWith("--")) {
    				String optionText = arg.substring(2);// 去掉--
    				String optionName;
    				String optionValue = null;
    				//获取参数=后面的内容,如--filePath=c:/data/1.txt最后得到的就是c:/data/1.txt
    				int indexOfEqualsSign = optionText.indexOf('=');
    				if (indexOfEqualsSign > -1) {// 如果有=号如--filePath=c:/data/1.txt
    					optionName = optionText.substring(0, indexOfEqualsSign);//获取=左边的值(filePath)
    					optionValue = optionText.substring(indexOfEqualsSign + 1);//获取=右边的值(c:/data/1.txt)
    				}
    				else {// 没有=号就直接赋值,如例子中的--debug,就直接将debug赋值
    					optionName = optionText;
    				}
    				commandLineArgs.addOptionArg(optionName, optionValue);// 【3】
    			}
    			else {
    				commandLineArgs.addNonOptionArg(arg);// 【4】 不是--开头的参数,直接添加
    			}
    		}
    		return commandLineArgs;
    	}
    }
    

    从上面这段代码【3】【4】可以看出,传入的参数可以分为两类:option和NonOption【这两个概念很重要】。
    以两个 – 开头的参数(比如- - debug)为option,其他的都为NonOption

    展开全文
  • 前言在命令行运行过程序的同学应该对命令的附加参数不陌生,比如我们在windows下的命令窗口中输入help rename,则它的显示如下:其输出说明了rename这个命令的用法,如果你仔细观察就会发现,它后面带的参数不止一个...
  • 命令行参数

    2011-10-12 11:06:00
    现在告诉你它有什么用:现在是...在程序中就可以通过它所带的参数而知道,使用者想怎么用它。使用者通过 -a 这个参数。告诉程序,要列出详细的信息。#include <stdio.h>int main(int argc, char *argv[]){ if(...
  • 的是vs2010
  • Jmeter命令行参数介绍

    2019-09-06 13:33:19
    一、使用命令行方式运行Jmeter 1.1为什么 使用GUI方式启动jmeter,运行线程较多的测试时,会造成内存和CPU的大量消耗,导致客户机卡死。...1.2怎么用 1.3示例 例1:bin目录下执行D:\性能测试\工...
  • 就这么一个小功能,我查了小半一天的资料,说的天花乱坠怎么干的都有。 其实没那么复杂,我这里说两种最简单的方法,不需要引入任何的第三方模块。 方法一: 命令行直接输入,不需要在package.json里配置: npm run ...
  • 通常他们会跟一些参数,这些参数又是怎么传入到命令里的呢。 这要从先从main()函数的标准写法说起 //demo.c #include &lt;stdio.h&gt; int main(int argc, char* argv[]) { return 0; } main()也是可以传...
  • 那我们先看下命令行参数代码怎么写?我们上一节写的main,是最普通的main,现在常用的就两种。 int main(void){} int main(int argc,char *argv[]){} 我们平时写的时候,的第一种,但我们写工具的时候,会第二...
  • C++Builder中取得命令行参数

    千次阅读 2007-07-22 10:59:00
    过C语言编程的人都知道,在DOS下的编程可以通过main函数的参数取得命令行参数的个数以及每个参数的字符串,例如int main(int argv ,char *argv[]){…} 则命令行参数是argc个,这些参数分别存储在argv[0]~argv...
  • 了这么久,还没怎么学习python的命令行参数,是在惭愧。 参考文章地址:http://www.cnblogs.com/jianboqi/archive/2013/01/10/2854726.html 自己的代码实例: #-*-coding:utf-8-*- __author__ = 'Deen' ...
  • 作为新手,之前总是很困扰,不知道怎么用。偶然的机会终于略知一二了。 在Visual Studio中,我们可以自行设置命令行参数。 如在这个示例程序中,我们想把图像存入argv[1]。 方法如下: 依次点击,项目、属性、...
  • 最近打算读一读 go程序设计语言这本书, 读语言类的书是一件十分头疼的事情, 因为读一本书就意味着,看着一堆钳子 锥子工具的图片, 概念背了一大堆,仍然不知道怎么用,还是要通过实践。 还是习惯任务驱动的方式。...
  • 前言在命令行运行过程序的同学应该对命令的附加参数不陌生,比如我们在windows下的命令窗口中输入help rename,则它的显示如下:其输出说明了rename这个命令的用法,如果你仔细观察就会发现,它后面带的参数不止一个...
  • CAD命令行不见了,怎么打开?命令行用于输入命令,显示命令参数,如下图所示。有时命令行被关闭了,给操作会带来很多困扰。打开命令行最简单的方法就是快捷键:CTRL+9,利用这个快捷键可以关闭或打开命令行,AutoCAD...
  • File f1 = new File("E:\\test\\test.txt"); 这个没有在Main方法里面,是写在单独的一个方法,用命令行怎么将文件的路径传递进来?
  • 举几个简单的例子吧,62616964757a686964616fe59b9ee7ad9431333337396333可以在终端先输入ls -l,可以看到当前目录下的文件信息,其中有一列如下:-rwx-r--r--(一共10个参数)第一个字符指定了文件类型。在通常意义上...
  • 若吾皇第一招、mysql服务的启动和停止net stop mysqlnet start mysql第二招、登陆mysql语法如下: mysql -u用户名 -p用户密码键入...注意,如果是连接到另外的机器上,则需要加入一个参数-h机器IP第三招、增加新...
  • 是否妙用取决于你怎么用 1、sys.argv是用来获取命令行参数的方法,本身是一个list。你搜其实用方法,这方面的介绍最多,这里不赘述 2、那么问题是:sys.argv可以赋值吗?可以扩充吗?可以修改吗? 答案见下图实例...
  • File f1 = new File("E:\\test\\changchun.SCI"); 我想用命令行把文件路径传递进来,怎么操作? 高手们,帮帮忙。。。
  • 在之前一篇文章《Java直接调用exe可执行文件传参并且获取返回值》我有讲Java程序如何调用exe可执行文件,并且有说在调用时怎么传参和接收返回的结果。这个时候很多小伙伴就会问了,所调用exe可执行文件如果是开源...
  • 那如果我的函数名是addfile,需要的参数格式是[]Sring,参数如下,该怎么写命令 [{"FileName":"1.txt","ID":"121","IPAdress":"1.1.1.2","OrgName":"org2","ModifyTime":"8:27 2019/9/12"},"eventAddFile"]...
  • 由于对GCC的参数一知半解,害我今天早上浪费了一个多小时。“以此文祭奠失去的时间” 1、生成静态链接库: 分两步 ...gcc默认要求库文件名必须...2、怎么用这个libaaa.a,有两种办法 g++ main.c -L"PATH_TO_AAA" -l
  • 高分求教 我PB做了2个程序,想第一个带参数执行第二个程序,第二个程序怎么判断并接受那个参数呢?
  • ``` parser = argparse.ArgumentParser() parser.add_argument('-k', '--keywords', help='delimited list input', type=str, required=False) parser.add_argument('-...这种程序,想在程序内部传参,怎么操作?

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 335
精华内容 134
关键字:

命令行参数怎么用