如何在 python 中加载带有参数的 python 模块?

Posted

技术标签:

【中文标题】如何在 python 中加载带有参数的 python 模块?【英文标题】:How to load a python module with arguments in python? 【发布时间】:2017-05-02 14:26:23 【问题描述】:

我想创建一个可以用python -m mymodule somefile.py some_arg some_arg 调用的python 模块。

我的想法是我可以设置一个别名alias="python -m mymodule" 并使用python somefile.py some_arg some_arg 正常调用文件。

在文件mymodule/__main__.py 中,加载somefile.py 并将参数列表传递给它的最佳方法是什么?

我正在寻找一个通用的解决方案,它可以兼容 python2 和 3。 尽可能少的打扰会很棒。如果somefile.py 会引发异常,那么mymodule 应该几乎不会在回溯中看到。 这个模块的作用在这里并不详细,但是它设置了一些python的东西(traceback hooks等),所以somefile.py应该在同一个进程中以pythonicly方式运行。 os.systemsubprocess.Popen 不适合。

【问题讨论】:

【参考方案1】:

好的,我找到了适合 python 3.5 的东西,并且对于 python 2.7 来说已经足够满足了。

mymodule/ma​​in.py

import sys

# The following block of code removes the part of 
# the traceback related to this very module, and runpy
# Negative limit support came with python 3.5, so it will not work
# with previous versions.
# https://docs.python.org/3.5/library/traceback.html#traceback.print_tb
def myexcepthook(type, value, tb):
     nb_noise_lines = 3
     traceback_size = len(traceback.extract_tb(tb))
     traceback.print_tb(tb, nb_noise_lines - traceback_size)
if sys.version_info >= (3, 5):
    sys.excepthook = myexcepthook

if len(sys.argv) > 1:
    file = sys.argv[1]
    sys.argv = sys.argv[1:]

    with open(file) as f:
         code = compile(f.read(), file, 'exec')
         exec(code)

somefile.py

import sys
print sys.argv
raise Exception()

在终端中

$ python3 -m mymodule somefile.py some_arg some_arg
['somefile.py', 'some_arg', 'some_arg']
Traceback (most recent call last):
  File "somefile.py", line 3, in <module>
    raise Exception()

$ python2 -m mymodule somefile.py some_arg some_arg
['somefile.py', 'some_arg', 'some_arg']
Traceback (most recent call last):
  File "/usr/lib64/python3.5/runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/azmeuk/dev/testpy/mymodule/__main__.py", line 16, in <module>
    exec(code)
  File "somefile.py", line 3, in <module>
    raise Exception()

$ python somefile.py some_arg some_arg
['somefile.py', 'some_arg', 'some_arg']
Traceback (most recent call last):
  File "somefile.py", line 3, in <module>
    raise Exception()
Exception

不过,如果有人有更好的提议,那就太好了!

【讨论】:

这是一个很好的解决方案。确保在mymodule/__main__.py 的全局字典中添加尽可能少的名称,因为somefile.py 不希望在其命名空间中包含这些对象。您还可以使用traceback.print_tb 中的limit 参数来显示干净的回溯。【参考方案2】:

我认为limit 的负值在 python 3.5 之前的 traceback 模块中不起作用。这是一个适用于 python 2.7 的丑陋 hack

import sys
import traceback

class ExcFile(object):
    def __init__(self, file):
        self.topline = True
        self.file = file

    def write(self, s):
        if self.topline:
            u, s = s.split('\n', 1)
            self.file.write(u +'\n')
            self.topline = False
        if '#---\n' in s:
            u, s = s.split('#---\n', 1)
            self.file.write(s)
            self.write = self.file.write

ExcFile._instance = ExcFile(sys.stdout)    
# The following block of code removes the part of 
# the traceback related to this very module, and runpy
def myexcepthook(type, value, tb):
    traceback.print_exception(type, value, tb, file=ExcFile._instance)
sys.excepthook = myexcepthook

if len(sys.argv) > 1:
    file = sys.argv[1]
    sys.argv = sys.argv[1:]

    with open(file) as f:
        code = compile(f.read(), file, 'exec')
        exec(code) #---

所有这些都应该写在一个单独的文件中,以避免混乱__main__.py

【讨论】:

以上是关于如何在 python 中加载带有参数的 python 模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 3 中加载/删除带有动画的自定义视图

如何在pig中加载带有制表符和逗号的数据集

如何在已经是 NIB 的 UICollectionViewCell 中加载带有自定义单元格的 UITable

在ios中加载html时如何在wkwebview中隐藏带有src的图像?

如何在Android中加载带有动画的cardview GridView?

当页面在带有nativescript的android应用程序中加载时如何显示键盘?