- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 Haskell 可执行文件中,使用 optparse-applicative
创建, 我想要 --version
的全局选项与全局一起--help
可从所有子命令获得的选项。然而 example provided (见下文)用于添加 --version
带有子命令的 CLI 选项会导致 --version
不一致可用的选项
$ cli create --version
Invalid option `--version'
Usage: cli create NAME
Create a thing
$ cli delete --version
0.0
$ cli create -h
Usage: cli create NAME
Create a thing
Available options:
NAME Name of the thing to create
-h,--help Show this help text
$ cli delete -h
Usage: cli delete
Delete the thing
Available options:
-h,--help Show this help text
--version
全局可用并适用于所有子命令:
$ cli create -h
Usage: cli create NAME
Create a thing
Available options:
NAME Name of the thing to create
--version Show version
-h,--help Show this help text
$ cli delete -h
Usage: cli delete
Delete the thing
Available options:
--version Show version
-h,--help Show this help text
$ cli create --version
0.0
$ cli delete --version
0.0
$ cli create -h
Usage: cli create NAME
Create a thing
Arguments:
NAME Name of the thing to create
Global options:
--version Show version
-h,--help Show this help text
$ cli delete -h
Usage: cli delete
Delete the thing
Global options:
--version Show version
-h,--help Show this help text
optparse-applicative
来实现这一点? ?
{-#LANGUAGE ScopedTypeVariables#-}
import Data.Semigroup ((<>))
import Options.Applicative
data Opts = Opts
{ optGlobalFlag :: !Bool
, optCommand :: !Command
}
data Command
= Create String
| Delete
main :: IO ()
main = do
(opts :: Opts) <- execParser optsParser
case optCommand opts of
Create name -> putStrLn ("Created the thing named " ++ name)
Delete -> putStrLn "Deleted the thing!"
putStrLn ("global flag: " ++ show (optGlobalFlag opts))
where
optsParser :: ParserInfo Opts
optsParser =
info
(helper <*> versionOption <*> programOptions)
(fullDesc <> progDesc "optparse subcommands example" <>
header
"optparse-sub-example - a small example program for optparse-applicative with subcommands")
versionOption :: Parser (a -> a)
versionOption = infoOption "0.0" (long "version" <> help "Show version")
programOptions :: Parser Opts
programOptions =
Opts <$> switch (long "global-flag" <> help "Set a global flag") <*>
hsubparser (createCommand <> deleteCommand)
createCommand :: Mod CommandFields Command
createCommand =
command
"create"
(info createOptions (progDesc "Create a thing"))
createOptions :: Parser Command
createOptions =
Create <$>
strArgument (metavar "NAME" <> help "Name of the thing to create")
deleteCommand :: Mod CommandFields Command
deleteCommand =
command
"delete"
(info (pure Delete) (progDesc "Delete the thing"))
最佳答案
据我所知,使用 optparse-applicative
处理这个(特别是分类的帮助文本)并不容易。 ,因为这不是他们计划使用全局参数的模式。如果您可以使用 program --global-options command --local-options
(这是一个相当标准的模式)而不是 program command --global-and-local-options
,那么您可以使用链接示例中显示的方法:
$ ./optparse-sub-example
optparse-sub-example - a small example program for optparse-applicative with
subcommands
Usage: optparse [--version] [--global-flag] COMMAND
optparse subcommands example
Available options:
-h,--help Show this help text
--version Show version
--global-flag Set a global flag
Available commands:
create Create a thing
delete Delete the thing
$ ./optparse-sub-example --version create
0.0
$ ./optparse-sub-example --version delete
0.0
$ ./optparse-sub-example --global-flag create HI
Created the thing named HI
global flag: True
$ ./optparse-sub-example --global-flag delete
Deleted the thing!
global flag: True
subparser
- 类似功能,可添加您的全局选项并将它们与命令之前的任何全局选项合并。 {-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ApplicativeDo #-}
import Data.Monoid
import Data.Semigroup ((<>))
import Options.Applicative
import Options.Applicative.Types
Opts
被明确分成
optGlobals
和
optCommand
,如果有更多可用选项,则可以轻松地一次处理所有全局选项:
data Opts = Opts
{ optGlobals :: !GlobalOpts
, optCommand :: !Command
}
data GlobalOpts = GlobalOpts { optGlobalFlag :: Bool }
GlobalOpts
应该是
Semigroup
和
Monoid
,因为我们需要合并在各个不同点(命令之前,命令之后等)看到的选项。也应该可以,对
mysubparser
进行适当的修改。下面,要求仅在命令之后给出全局选项并省略此要求。
instance Semigroup GlobalOpts where
-- Code for merging option parser results from the multiple parsers run
-- at various different places. Note that this may be run with the default
-- values returned by one parser (from a location with no options present)
-- and the true option values from another, so it may be important
-- to distinguish between "the default value" and "no option" (since "no
-- option" shouldn't override another value provided earlier, while
-- "user-supplied value that happens to match the default" probably should).
--
-- In this case this doesn't matter, since the flag being provided anywhere
-- should be enough for it to be considered true.
(GlobalOpts f1) <> (GlobalOpts f2) = GlobalOpts (f1 || f2)
instance Monoid GlobalOpts where
-- Default values for the various options. These should probably match the
-- defaults used in the option declarations.
mempty = GlobalOpts False
Command
键入以表示不同的可能命令:
data Command
= Create String
| Delete
mysubparser
包裹
hsubparser
添加全局选项并处理合并它们。它将全局选项的解析器作为参数:
mysubparser :: forall a b. Monoid a
=> Parser a
-> Mod CommandFields b
-> Parser (a, b)
mysubparser globals cmds = do
g1 <- globals
hsubparser
获取命令解析器,并将其修改为也解析全局选项:
(g2, r) <- addGlobals $ hsubparser cmds
pure (g1 <> g2, r)
where
addGlobals
辅助功能:
addGlobals :: forall c. Parser c -> Parser (a, c)
NilP
已给出,我们只使用
mempty
获取默认选项集:
addGlobals (NilP x) = NilP $ (mempty,) <$> x
OptP
围绕
Option
使用
CommandReader
,
globals
解析器被添加到每个命令解析器中:
addGlobals (OptP (Option (CmdReader n cs g) ps)) =
OptP (Option (CmdReader n cs $ fmap go . g) ps)
where go pi = pi { infoParser = (,) <$> globals <*> infoParser pi }
Parser
合并选项集视情况而定:
addGlobals (OptP o) = OptP ((mempty,) <$> o)
addGlobals (AltP p1 p2) = AltP (addGlobals p1) (addGlobals p2)
addGlobals (MultP p1 p2) =
MultP ((\(g2, f) -> \(g1, x) -> (g1 <> g2, f x)) <$> addGlobals p1)
(addGlobals p2)
addGlobals (BindP p k) = BindP (addGlobals p) $ \(g1, x) ->
BindP (addGlobals $ k x) $ \(g2, x') ->
pure (g1 <> g2, x')
main
的修改功能相当少,主要与使用新的
GlobalOpts
相关。 .曾经是
GlobalOpts
的解析器可用,将其传递给
mysubparser
很容易:
main :: IO ()
main = do
(opts :: Opts) <- execParser optsParser
case optCommand opts of
Create name -> putStrLn ("Created the thing named " ++ name)
Delete -> putStrLn "Deleted the thing!"
putStrLn ("global flag: " ++ show (optGlobalFlag (optGlobals opts)))
where
optsParser :: ParserInfo Opts
optsParser =
info
(helper <*> programOptions)
(fullDesc <> progDesc "optparse subcommands example" <>
header
"optparse-sub-example - a small example program for optparse-applicative with subcommands")
versionOption :: Parser (a -> a)
versionOption = infoOption "0.0" (long "version" <> help "Show version")
globalOpts :: Parser GlobalOpts
globalOpts = versionOption <*>
(GlobalOpts <$> switch (long "global-flag" <> help "Set a global flag"))
programOptions :: Parser Opts
programOptions =
uncurry Opts <$> mysubparser globalOpts (createCommand <> deleteCommand)
createCommand :: Mod CommandFields Command
createCommand =
command
"create"
(info createOptions (progDesc "Create a thing"))
createOptions :: Parser Command
createOptions =
Create <$>
strArgument (metavar "NAME" <> help "Name of the thing to create")
deleteCommand :: Mod CommandFields Command
deleteCommand =
command
"delete"
(info (pure Delete) (progDesc "Delete the thing"))
mysubparser
应该是一个非常通用/可重用的组件。
$ ./optparse-sub-example create --global-flag HI
Created the thing named HI
global flag: True
$ ./optparse-sub-example --global-flag create HI
Created the thing named HI
global flag: True
$ ./optparse-sub-example --global-flag delete
Deleted the thing!
global flag: True
$ ./optparse-sub-example delete --global-flag
Deleted the thing!
global flag: True
$ ./optparse-sub-example delete
Deleted the thing!
global flag: False
$ ./optparse-sub-example delete --version
0.0
$ ./optparse-sub-example create --version
0.0
关于haskell - 如何使用 'optparse-applicative' 创建和区分全局选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53769310/
我正在尝试使用 optparse-applicative程序中的库应根据参数的数量执行不同的操作。 例如,计算周长的程序的参数解析: module TestOpts where import Opti
./hello_world -c arg1 arg2 arg3 是否可以通过编码使选项 -c 仅获得两个参数(arg1 和 arg2)? parser.add_option("-c",
我正在使用 optparse,最近遇到以下问题 - 我想将目录名称作为参数传递。像这样的东西: ./script.py --dir c:\a\b 但是,optparse 消除了“\”符号,因此相关变量
我有一个 mysql 数据库,我正在尝试打印特定学生的所有测试结果。我正在尝试创建一个命令行,在其中输入用户名,然后它将显示他/她的测试结果。我已经访问过此页面,但无法得到答案。 optparse a
通常,可以不带任何参数地调用 optparse 的方法 parse_args。但是,如果需要提供与 sys.argv 不同的参数集,则可以传递给 parse_args。 但是,如果需要将字符串而不是列
我正在开发一个接收一些参数并希望其中一些参数成为必需参数的程序,但我遇到了一些问题: 我确实需要使代码与 Python 2.4.x 兼容,所以我(至少是这么认为)只能使用 optparse 希望避免代
有没有办法让下面的工作?我正在寻找的是根据另一个选项的值获得一个选项的值。 import optparse parser = optparse.OptionParser() parser.add_op
请说明为什么下面的代码给出了错误,尽管两者都表示相同的选项。 In [3]: parser = optparse.OptionParser() In [4]: parser.add_option("-
我是 Python 的新手,并且在玩 optparse。我有这样的解析器功能: def parse(argv): """Option parser, returns the options l
我正在尝试使用 optparse,但遇到问题。 我的脚本用法是:script 我不打算添加任何选项字符串,例如:script -f 或script --file 有什么方法可以选择不传递参数字符串
我编写了一个最多接受 4 个选项和 2 个参数的函数。选项包括 -1、-2、-3 和 -u。默认情况下,它们的值分别设置为 true、true、true 和 false,但启用任何选项都会导致该值翻转
我想将数据传递给脚本,就像这样 if __name__ == '__main__': usage = 'python pull.py [-h ][-p ][-r ]arg1[,arg2..]'
if __name__=='__main__': parser = OptionParser() parser.add_option("-i", "--input_file",
我遇到了以下有趣的错误: parser.add_option("-n", "--number", metavar="NUMBER", type="int", hel
我目前正在学习如何使用 Python optparse 模块。我正在尝试以下示例脚本,但 args 变量结果为空。我使用 Python 2.5 和 2.6 进行了尝试,但无济于事。 import op
我试图更好地了解 optparse,但我很难理解为什么以下代码会这样运行。我在做傻事吗? import optparse def store_test(option, opt_str, value,
我正在编写一个 python 脚本,我希望它能够从命令行调用并作为库函数导入。理想情况下,命令行选项和函数应使用同一组默认值。允许我在两个地方重复使用一组默认值的最佳方法是什么? 这是具有重复默认值的
采用以下相当标准的代码: from optparse import OptionParser opts = OptionParser() opts.ad
当使用 optparse 时,我想在一个选项之后获取整个字符串,但我只获取到第一个空格的一部分。 例如: python myprog.py --executable python someOtherP
是否有 optparse (command line option parser) 的 C# 端口?来自 Python 的模块在一些 OSI-approved license 下可用? 最佳答案 你看
我是一名优秀的程序员,十分优秀!