有没有办法在Jupyter笔记本单元格中使用点击库? 我想将标志传递给笔记本中的Jupyter笔记本代码 让它更顺畅地转换到独立的脚本。例如,使用 来自Jupyter笔记本电脑的OptionParser:
from optparse import OptionParser
import sys
def main():
parser = OptionParser()
parser.add_option('-f', '--fake',
default='False',
help='Fake data')
(options,args) = parser.parse_args()
print('options:{} args: {}'.format(options, args))
if options.fake:
print('Fake detected')
def test_args():
print('hello')
if __name__ == '__main__':
sys.argv = ['--fake', 'True' '--help']
main()
输出: 选项:{'假':'错误'} args:[' True - help'] 检测到假冒
使用点击库,我收到一串错误。我运行了这个代码 Jupyter笔记本电池:
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s!' % name)
if __name__ == '__main__':
hello()
输出(截断):
UnsupportedOperation Traceback (most recent call last)
<ipython-input-6-ad31be7bf0fe> in <module>()
12 if __name__ == '__main__':
13 sys.argv = ['--count', '3']
---> 14 hello()
~/.local/lib/python3.6/site-packages/click/core.py in __call__(self, *args, **kwargs)
720 def __call__(self, *args, **kwargs):
721 """Alias for :meth:`main`."""
--> 722 return self.main(*args, **kwargs)
723
724
...
257
258 if message:
--> 259 file.write(message)
260 file.flush()
261
UnsupportedOperation: not writable
答案 0 :(得分:2)
您可以使用%%python
magic命令启动新的Python propcess:
%%python
import sys
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
with open('echo.txt', 'w') as fobj:
for x in range(count):
click.echo('Hello %s!' % name)
if __name__ == '__main__':
# first element is the script name, use empty string instead
sys.argv = ['', '--name', 'Max', '--count', '3']
hello()
输出:
Hello Max!
Hello Max!
Hello Max!
答案 1 :(得分:2)
Jupyter劫持了stdout / stderr / stdin feed。您可以使用import sys; type(sys.stdin)
来查看此内容,其中ipykernel.iostream.OutStream
。让jupyter和click一起操作的解决方法是直接将sys.stdout
传递给click。
def monkey_patch_jupyter_click_sreams():
"""see https://stackoverflow.com/a/49595790/221742 ."""
import sys
import ipykernel
import click
if not click._compat.PY2 and isinstance(sys.stdout, ipykernel.iostream.OutStream):
click._compat._force_correct_text_writer = lambda stream, encoding, errors: stream
monkey_patch_jupyter_click_sreams()
# your code here
hello()
这可以绕过stdout和其他流的click包装器,然后传递stdout._buffer。即使stdout已替换为ipythons ipykernel.iostream.OutStream
,这也适用于点击。