让Python在我的脚本之前运行几行

时间:2015-08-24 14:10:05

标签: python python-import

我需要运行一个脚本foo.py,但我还需要在foo.py中的代码之前插入一些调试行。目前我只是将这些行放在foo.py中,我小心不要将其提交给Git,但我不喜欢这个解决方案。

我想要的是一个单独的文件bar.py我不会向Git提交。然后我想跑:

python /somewhere/bar.py /somewhere_else/foo.py

我想要做的是首先在bar.py中运行一些代码行,然后将foo.py作为__main__运行。它应该在bar.py行运行的同一过程中,否则调试行不会有帮助。

有没有办法让bar.py这样做?

有人建议:

import imp
import sys

# Debugging code here

fp, pathname, description = imp.find_module(sys.argv[1])
imp.load_module('__main__', fp, pathname, description)

问题在于,因为它使用导入机制,我需要与foo.py在同一个文件夹上运行它。我不想要那个。我想简单地完成foo.py的完整路径。

此外:该解决方案还需要使用.pyc个文件。

5 个答案:

答案 0 :(得分:13)

Python有一种在启动时运行代码的机制; site模块。

"This module is automatically imported during initialization."

站点模块将在导入sitecustomize之前尝试导入名为__main__的模块。 如果您的环境指示它,它还将尝试导入名为usercustomize的模块。

例如,您可以将sitecustomize.py文件放在包含以下内容的site-packages文件夹中:

import imp

import os

if 'MY_STARTUP_FILE' in os.environ:
    try:
        file_path = os.environ['MY_STARTUP_FILE']
        folder, file_name = os.path.split(file_path)
        module_name, _ = os.path.splitext(file_name)
        fp, pathname, description = imp.find_module(module_name, [folder])
    except Exception as e:
        # Broad exception handling since sitecustomize exceptions are ignored
        print "There was a problem finding startup file", file_path
        print repr(e)
        exit()

    try:
        imp.load_module(module_name, fp, pathname, description)
    except Exception as e:
        print "There was a problem loading startup file: ", file_path
        print repr(e)
        exit()
    finally:
        # "the caller is responsible for closing the file argument" from imp docs
        if fp:
            fp.close()

然后你可以像这样运行你的脚本:

MY_STARTUP_FILE=/somewhere/bar.py python /somewhere_else/foo.py
  • 您可以在foo.py之前运行任何脚本,而无需添加代码以重新导入__main__
  • 运行export MY_STARTUP_FILE=/somewhere/bar.py,无需每次都引用

答案 1 :(得分:7)

如果文件为.py,则可以使用execfile();如果文件为.pyc,则可以使用uncompyle2

我们假设你的文件结构如下:

test|-- foo.py
    |-- bar
         |--bar.py   

<强> foo.py

import sys

a = 1
print ('debugging...')

# run the other file
if sys.argv[1].endswith('.py'): # if .py run right away
    execfile(sys.argv[1], globals(), locals())
elif sys.argv[1].endswith('.pyc'): # if .pyc, first uncompyle, then run
    import uncompyle2
    from StringIO import StringIO
    f = StringIO()
    uncompyle2.uncompyle_file(sys.argv[1], f)
    f.seek(0)
    exec(f.read(), globals(), locals())

<强> bar.py

print a
print 'real job'

test/,如果你这样做:

$ python foo.py bar/bar.py
$ python foo.py bar/bar.pyc

两者都输出相同的内容:

debugging...
1
real job

另请参阅此answer

答案 2 :(得分:0)

foo.py不必与主文件夹位于同一文件夹中。使用

export PYTHONPATH=$HOME/dirWithFoo/:$PYTHONPATH

添加foo所在的路径到Python路径。现在你可以

from foo import myfunc

myfunc()

让myfunc做你想做的事情

答案 3 :(得分:0)

你试过这个吗?

bar.py

imp.load_source('__main__', '../../foo.py')

对我来说它运行在foo.py中的任何内容(在 main 之前和之内)

之后,也许你在bar.py中所做的事情可能比我的基本测试更棘手。

load_source的好处是,如果它已经存在,它会导入.pyc或者启动&#34;编译&#34; .py然后导入.pyc。

答案 4 :(得分:0)

这个解决方案最终适合我:

#!/usr/bin/env python

import imp
import sys
import os.path

file_path = sys.argv.pop(1)
assert os.path.exists(file_path)

folder, file_name = os.path.split(file_path)

###############################################################################
#                                                                             #

# Debugging cruft here

#                                                                             #
###############################################################################


module_name, _ = os.path.splitext(file_name)
sys.path.append(folder)
imp.load_module('__main__', *imp.find_module(module_name))