提问人:novski 提问时间:2/7/2023 更新时间:2/8/2023 访问量:116
如何使用 argparse 中的位置参数。Namespace
how to use positional argument from argparse.Namespace
问:
我正在尝试在两个文件中构建一个 cli 和 wxpython gui 应用程序。
wx 应用调用 cli 应用以获取功能。
当我将 wx 应用程序中的参数包装到命名空间时,cli 应用程序不会接受它。window.py: error: the following arguments are required: filepath
我简化了文件以仅显示相关部分:
window.py
import os
from argparse import Namespace
from threading import Thread
from main import main
def window():
try:
print('window try')
args = Namespace(
filepath = os.getcwd()+'file.xy',
outputpath = os.getcwd()
)
thread = Thread(target=main, args=(args,))
thread.start()
thread.join()
except Exception as e:
print(f'error:{e}')
if __name__ == '__main__':
window()
main.py
import os
import argparse
def main(*args):
print(f'START main args:{args}, type of args:{type(args)}')
if args:
args=args[0]
print(f'tuple0:{args}, type of args:{type(args)}')
parser = argparse.ArgumentParser()
parser.add_argument('filepath', default=os.getcwd())
parser.add_argument('-o', dest='outputpath')
args = parser.parse_args()
print(f'DONE main args:{args}, type of args:{type(args)}')
if __name__ == '__main__':
main()
输出:
➜ argparse python3 main.py ~/Documents/
START main args:(), type of args:<class 'tuple'>
tuple0:(), type of args:<class 'tuple'>
DONE main args:Namespace(filepath='/Users/novski/Documents/', outputpath=None), type of args:<class 'argparse.Namespace'>
➜ argparse python3 window.py
window try
START main args:(Namespace(filepath='/Users/novski/Documents/argparse/file.xy', outputpath='/Users/novski/Documents/argparse'),), type of args:<class 'tuple'>
tuple0:Namespace(filepath='/Users/novski/Documents/argparse/file.xy', outputpath='/Users/novski/Documents/argparse'), type of args:<class 'argparse.Namespace'>
usage: window.py [-h] [-o OUTPUTPATH] filepath
window.py: error: the following arguments are required: filepath
为什么当我把它从我的 window.py 交给 main.py 时没有被接受?Namespace(filepath...
filepath
args
有没有更好的解决方案,如何从 GUI (window.py) 使用我的 cli 应用程序 (main.py)?
答:
1赞
hpaulj
2/8/2023
#1
有条件地运行解析器怎么样?
if args:
args=args[0]
print(f'tuple0:{args}, type of args:{type(args)}')
else:
parser = argparse.ArgumentParser()
parser.add_argument('filepath', default=os.getcwd())
parser.add_argument('-o', dest='outputpath')
args = parser.parse_args()
0赞
chepner
2/8/2023
#2
您需要传递希望解析器解析的字符串列表,而不是它最终可能返回的对象。
def window():
try:
print('window try')
args = ['-o', os.getcwd(), os.getcwd() + 'file.xy']
thread = Thread(target=main, args=(args,))
thread.start()
thread.join()
except Exception as e:
print(f'error:{e}')
和
# Parse args will parse whatever list main() receives, or sys.argv[1:]
# if nothing is given to main().
def main(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('filepath', default=os.getcwd())
parser.add_argument('-o', dest='outputpath')
args = parser.parse_args(args)
print(f'DONE main args:{args}, type of args:{type(args)}')
0赞
CristiFati
2/8/2023
#3
列出 [Python.Docs]: argparse - 命令行选项、参数和子命令的解析器。
我修复了您代码中的错误:
将 main 接收到的参数传递给 parse_args(而不是依赖于 sys.argv)
删除(不知道它是干什么用的,而且它很丑(看起来像是解决错误))
if args: args = args[0]
放弃命名空间(因为默认的命名空间绰绰有余)
将参数作为序列传递给 main(在(上面的)URL 中多次举例)
此外,将解析选项更改为(我认为是)用户友好的表单
演示:
main.py:
#!/usr/bin/env python import argparse import os import sys def main(*argv): print(f"Start main: {argv}") parser = argparse.ArgumentParser() parser.add_argument("--filepath", "-f", default=os.getcwd()) parser.add_argument("--outputpath", "-o",) parsed_args = parser.parse_args(args=argv) print(f"Parsed arguments: {parsed_args}") if __name__ == "__main__": print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) rc = main(*sys.argv[1:]) print("\nDone.\n") sys.exit(rc)
window.py:
#!/usr/bin/env python import os import sys from threading import Thread from main import main def window(): try: print("Start wwindow") args = ("-f", os.path.join(os.getcwd(), "file.py"), "-o", os.getcwd()) thread = Thread(target=main, args=args) thread.start() thread.join() except Exception as e: print(f"Exception: {e}") if __name__ == "__main__": print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) rc = window() print("\nDone.\n") sys.exit(rc)
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q075373104]> sopr.bat ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" ./main.py Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 Start main: () Parsed arguments: Namespace(filepath='e:\\Work\\Dev\\StackOverflow\\q075373104', outputpath=None) Done. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" ./main.py -f file Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 Start main: ('-f', 'file') Parsed arguments: Namespace(filepath='file', outputpath=None) Done. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" ./main.py -f file -o dir Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 Start main: ('-f', 'file', '-o', 'dir') Parsed arguments: Namespace(filepath='file', outputpath='dir') Done. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" ./window.py Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 Start wwindow Start main: ('-f', 'e:\\Work\\Dev\\StackOverflow\\q075373104\\file.py', '-o', 'e:\\Work\\Dev\\StackOverflow\\q075373104') Parsed arguments: Namespace(filepath='e:\\Work\\Dev\\StackOverflow\\q075373104\\file.py', outputpath='e:\\Work\\Dev\\StackOverflow\\q075373104') Done.
评论
parser.parse_args()
解析。事实上,你已经有一个变量被调用,但并不会改变这种行为。sys.argv
args