如何使用 python 中的参数加载 python 模块?

How to load a python module with arguments in python?

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

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

正常调用文件

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

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

我的模块/main.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

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

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

的丑陋技巧
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