如何执行一个 * . PY 文件从一个 * . IPYNB 文件在木星笔记本?

我的工作是一个 Python 笔记本,我希望该 大输入代码[输入] 打包到[ * . PY ]文件中,并从笔记本中调用这些文件

运行[ .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 ]文件的操作从零开始...)

有办法解决吗?

这个问题的一个可能的简化例子如下:

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

其中“ Script.py”包含以下内容:

plt.plot(x, f(x))
plt.xlabel("Eje $x$",fontsize=16)
plt.ylabel("$f(x)$",fontsize=16)
plt.title("Funcion $f(x)$")
  • 在实际问题中,文件[ * . PY ]没有4行代码,它有足够多的代码。
206750 次浏览

Maybe not very elegant, but it does the job:

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

In the %run magic documentation you can find:

-i run 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.

Therefore, supplying -i does the trick:

%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 x variable come from? and what is the f function?).

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 autoreload comes to your help.

Your example would look like this:
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

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

the below lines would also work

!python script.py
!python 'script.py'

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

Also the same can be done by just calling the module using the %run magic as follows:

%run -m script

where -m is your module i.e. script.py but using this just supplying script would also do the job.