针对Jupyter Notebook中使用argparse报错的问题,可以采用以下的解决方案:
问题描述
在Jupyter Notebook中使用argparse时,可能会出现以下类似的报错信息:
usage: ipykernel_launcher.py [-h] [--input INPUT] [--output OUTPUT]
ipykernel_launcher.py: error: unrecognized arguments: -f /run/user/1000/jupyter/kernel-fc2244b4-7843-406e-991d-3f9705ba9e7e.json
这个问题的主要原因是Jupyter Notebook的默认启动方式中会添加一些不必要的参数,以致于argparse的解析器会出现错误。
解决方案
方案一:修改Kernel启动脚本
在Jupyter Notebook的启动方法中,新增Kernel启动脚本
的参数$kernel_cmd
来传入Kernel的起始参数,可以避免默认参数的影响。修改jupyter_kernel_mgmt.py
文件,添加一个可选参数--
,示例如下:
c.KernelManager.kernel_cmd = [
'python',
'-m',
'ipykernel_launcher',
'-f',
'{connection_file}',
'--',
"{sys.executable}",
"-m",
"ipykernel_launcher",
"-f",
"{connection_file}"
]
这里的--
表示后面的所有参数都是用户手动指定的,不是默认添加的。这种方式的优点是可以避免原有的功能受到影响,但需要到系统目录下修改文件,操作较繁琐。
方案二:利用ipykernel的启动包装器
ipykernel有一个专门用来包装启动器的方法,只需要在首行加上#!/usr/bin/env python
后,导入IPython.kernel.zmq.kernelapp
中的IPKernelApp
,然后使用.parse_command_line
方法就可以得到完整的命令行参数列表了,例如:
#!/usr/bin/env python
from IPython.kernel.zmq.kernelapp import IPKernelApp
from traitlets.config import Config
if __name__ == '__main__':
# 注意 .parse_command_line 返回的是 dict
kwargs = IPKernelApp.parse_command_line()
c = Config()
...
这种方式相对简单,并且不需要修改系统文件,是较为推荐的解决方案之一。
示例说明
为了更好地说明问题,下面给出两个示例:
示例一:简单的命令行程序
下面是一个简单的命令行程序,用于对输入的文本进行大小写转换:
import argparse
def do_convert(input_file, output_file, upper):
with open(input_file, 'r') as f:
text = f.read()
if upper:
text = text.upper()
else:
text = text.lower()
with open(output_file, 'w') as f:
f.write(text)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Convert text file to uppercase or lowercase')
parser.add_argument('--input', required=True, help='input file path')
parser.add_argument('--output', required=True, help='output file path')
parser.add_argument('--upper', action='store_true', help='convert to uppercase')
parser.add_argument('--lower', action='store_true', help='convert to lowercase')
args = parser.parse_args()
if args.upper and args.lower:
print("Error: cannot specify both --upper and --lower")
elif not args.upper and not args.lower:
print("Error: must specify either --upper or --lower")
else:
do_convert(args.input, args.output, args.upper)
在Jupyter Notebook中执行这个程序时,输入如下命令:
%run convert.py --input=input.txt --output=output.txt --upper
就会出现上面提到的报错信息。此时可以采用方案一或方案二中的任意一种方法解决这个问题。
示例二:使用argparse提供服务
下面是一个使用argparse提供服务的示例,用于对输入的数字进行加法或乘法运算:
from argparse import ArgumentParser
from http.server import HTTPServer, BaseHTTPRequestHandler
class MathHandler(BaseHTTPRequestHandler):
def do_GET(self):
query = self.path.split('?')[1]
args = dict(qc.split("=") for qc in query.split("&"))
a, b = int(args['a']), int(args['b'])
if args.get('op', 'add') == 'add':
result = a + b
else:
result = a * b
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(str(result).encode())
if __name__ == '__main__':
parser = ArgumentParser(description="Run a simple HTTP server to perform math operations")
parser.add_argument('--port', default=8888, type=int, help="port to listen on")
args = parser.parse_args()
server = HTTPServer(('0.0.0.0', args.port), MathHandler)
print('Listening on port', args.port)
server.serve_forever()
执行这个程序时,输入如下命令:
%run math_service.py --port=8888
也会出现上面提到的报错信息。同样,此时可以采用方案一或方案二中的任意一种方法解决这个问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Jupyter Notebook内使用argparse报错的解决方案 - Python技术站