Python 如何从 Jupyter 笔记本上的 * .IPYNB 文件执行 * .PY 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42163470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 21:19:08  来源:igfitidea点击:

How to execute a * .PY file from a * .IPYNB file on the Jupyter notebook?

pythonjupyter

提问by JMSH

I am working on a Python Notebook and I would like that large input code [input]pack into a [* .PY] files and call this files from the notebook.

我正在使用 Python Notebook,我希望将大输入代码 [input]打包到 [* .PY] 文件中,并从 notebook 中调用此文件

The action of running a [.PY] file from the Notebook is known to me and the command varies between Linux or Windows. But when I do this action and execute the [.PY] file from the notebook, it does not recognize any existing library or variable loaded in the notebook (it's like the [.PY] file start from zero...).

我知道从 Notebook运行 [ .PY] 文件的操作,并且命令在 Linux 或 Windows 之间有所不同。但是,当我执行此操作并从笔记本执行 [.PY] 文件时,它无法识别笔记本中加载的任何现有库或变量(就像 [.PY] 文件从零开始...)

Is there any way to fix this?

有没有什么办法解决这一问题?

A possible simplified example of the problem would be the following:

该问题的一个可能的简化示例如下:

In[1]:
import numpy as np
import matplotlib.pyplot as plt

In[2]:
def f(x):
    return np.exp(-x ** 2)

In[3]:
x = np.linspace(-1, 3, 100)

In[4]:
%run script.py

Where "script.py" has the following content:

其中“ script.py”具有以下内容:

plt.plot(x, f(x))
plt.xlabel("Eje $x$",fontsize=16)
plt.ylabel("$f(x)$",fontsize=16)
plt.title("Funcion $f(x)$")
  • In the real problem, the file [* .PY] does not have 4 lines of code, it has enough more.
  • 在真正的问题中,文件 [* .PY] 没有 4 行代码,它有足够多的代码。

回答by swenzel

In the %runmagic documentationyou can find:

%run魔术文档中,您可以找到:

-irun the file in IPython's namespace instead of an empty one. This is useful if you are experimenting with code written in a text editor which depends on variables defined interactively.

-i在 IPython 的命名空间而不是空命名空间中运行文件。如果您正在试验在文本编辑器中编写的代码,该代码依赖于交互式定义的变量,这将非常有用。

Therefore, supplying -idoes the trick:

因此,提供-i可以解决问题:

%run -i 'script.py'


The "correct" way to do it

“正确”的方式来做到这一点

Maybe the command above is just what you need, but with all the attention this question gets, I decided to add a few more cents to it for those who don't know how a more pythonic way would look like.
The solution above is a little hacky, and makes the code in the other file confusing (Where does this xvariable come from? and what is the ffunction?).

也许上面的命令正是你所需要的,但是由于这个问题得到了所有的关注,我决定为那些不知道更 Pythonic 的方式看起来如何的人多加几美分。
上面的解决方案有点hacky,并且使另一个文件中的代码变得混乱(这个x变量来自哪里?f函数是什么?)。

I'd like to show you how to do it without actually having to execute the other file over and over again.
Just turn it into a module with its own functions and classes and then import it from your Jupyter notebook or console. This also has the advantage of making it easily reusable and jupyters contextassistant can help you with autocompletion or show you the docstring if you wrote one.
If you're constantly editing the other file, then autoreloadcomes to your help.

我想向您展示如何做到这一点,而实际上不必一遍又一遍地执行另一个文件。
只需将其转换为具有自己的函数和类的模块,然后从您的 Jupyter 笔记本或控制台导入即可。这还具有使其易于重用的优点,并且 jupyters contextassistant 可以帮助您进行自动完成或在您编写文档字符串时向您显示文档字符串。
如果您一直在编辑另一个文件,那么这autoreload对您有帮助。

Your example would look like this:
script.py

您的示例如下所示:
script.py

import matplotlib.pyplot as plt

def myplot(f, x):
    """
    :param f: function to plot
    :type f: callable
    :param x: values for x
    :type x: list or ndarray

    Plots the function f(x).
    """
    # yes, you can pass functions around as if
    # they were ordinary variables (they are)
    plt.plot(x, f(x))
    plt.xlabel("Eje $x$",fontsize=16)
    plt.ylabel("$f(x)$",fontsize=16)
    plt.title("Funcion $f(x)$")

Jupyter console

Jupyter 控制台

In [1]: import numpy as np

In [2]: %load_ext autoreload

In [3]: %autoreload 1

In [4]: %aimport script

In [5]: def f(x):
      :     return np.exp(-x ** 2)
      :
      :

In [6]: x = np.linspace(-1, 3, 100)

In [7]: script.myplot(f, x)

In [8]: ?script.myplot
Signature: script.myplot(f, x)
Docstring:
:param f: function to plot
:type f: callable
:param x: x values
:type x: list or ndarray
File:      [...]\script.py
Type:      function

回答by braj

the below lines would also work

以下几行也可以使用

!python script.py

回答by cyprieng

Maybe not very elegant, but it does the job:

也许不是很优雅,但它可以完成工作:

exec(open("script.py").read())

回答by cyprieng

!python 'script.py'

!python 'script.py'

replace script.py with your real file name, DON'T forget ''

用你的真实文件名替换 script.py,不要忘记 ''