代码之家  ›  专栏  ›  技术社区  ›  Oppy

在jupyter notebook cell中使用click library

  •  7
  • Oppy  · 技术社区  · 7 年前

    有没有办法在Jupyter笔记本电脑单元中使用click library? 我想将标志传递给我的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()
    

    输出: 选项:{'fake':'False}参数:['True--帮助'] 检测到虚假

    使用click库,我得到了一系列错误。我从一个 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
    
    2 回复  |  直到 7 年前
        1
  •  4
  •   Mike Müller    7 年前

    您可以使用 %%python 启动新Python进程的magic命令:

    %%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!
    
        2
  •  2
  •   wassname    7 年前

    Jupyter劫持了stdout/stderr/stdin提要。您可以使用 import sys; type(sys.stdin) ,它给出 ipykernel.iostream.OutStream . 让jupyter和click一起操作的一个解决方法是 sys.stdout 直接单击。

    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来实现_缓冲器即使stdout已被ipythons取代,这也可以与click一起使用 ipykernel。iostream。扩展 .