加载模块后运行Python启动代码

时间:2017-03-29 12:31:52

标签: python apache-spark ipython pyspark

我正在使用带有SparkContext的Jupyter笔记本和Python内核。一位同事编写了一些Python代码,用于通过ipykernel事件连接Spark事件。当我们从笔记本单元导入他的模块时,它适用于我们需要支持的所有组合:Python 2.7和3.5,Spark 1.6和2.x,仅限Linux。

现在我们要为所有Python内核自动启用该代码。我把导入到我们的sitecustomize.py。这适用于Spark 2.x,但不适用于Spark 1.6。使用Spark 1.6的内核不再获得sc,并且有些东西如此搞砸,以至于像matplotlib.cbook之类的无关导入失败了。当我使用计时器延迟导入几秒钟时,它可以工作。 显然,sitecustomize.py中的代码执行得太早,无法导入连接Spark和ipykernel的模块。

我正在寻找一种方法来延迟导入,直到Spark和/或ipykernel完全初始化。但在任何笔记本单元执行之前,它仍应作为内核启动的一部分执行。 我发现this trick延迟了代码执行,直到sys.argv被初始化。但我认为它不能用于像sc这样的全局变量,因为Python全局变量仍然是模块的本地变量。到目前为止,我能想到的最好的方法是使用计时器每秒检查sys.modules中是否存在某些模块。但这不是很可靠,因为我不知道如何区分完全初始化的模块和仍在加载过程中的模块。

关于如何挂钩在启动期间执行较晚的启动代码的任何想法?特定于pyspark和/或ipykernel的解决方案将满足我的需求。

1 个答案:

答案 0 :(得分:2)

嗯,你并没有详细说明你遇到的错误。

我认为为ipython内核定制启动行为的规范方法是设置配置文件并设置exec_lines选项。

例如,您可以放入~/.ipython/profile_default/ipython_config.py

# sample ipython_config.py
c = get_config()

c.InteractiveShellApp.exec_lines = [
    'import numpy',
    'import scipy'
]
c.InteractiveShellApp.exec_files = [
    'mycode.py',
    'fancy.ipy'
]