Python - 如何在另一个模块中调用模块的主要功能?

Posted

技术标签:

【中文标题】Python - 如何在另一个模块中调用模块的主要功能?【英文标题】:Python - How to call the main fuction of a module in another module? 【发布时间】:2016-05-30 00:57:54 【问题描述】:

我正在尝试编写一个python模块,它在其主函数中调用另一个模块的主函数。

我正在编写的模块称为 Trial.py,包含要调用的函数的模块称为print_all.py

print_all.py 是一个模块,是一个名为 mrtparse 的库。该库可以在here找到。

请注意,当我在 Linux shell 中运行 print_all.py 时,它需要一个文件 (.gz) 作为参数,如下所示

$ python print_all.py updates.gz

Trial.py 看起来像这样:

from mrtparse import *
import gzip
import print_all   
import os
from urllib2 import urlopen, URLError, HTTPError

def fn1():
    Bla Bla

def fn2():
    Bla Bla

def main():
    mrtparse.print_all.main(updates.gz)  //I want to do something like this

if __name__ == '__main__':
    main()

作为参数传递的所有模块和文件都在同一个目录中。 这似乎是一件容易做的事情,但我却很难做到。

【问题讨论】:

【参考方案1】:

您可以在脚本中将 main() 放在 else 语句中而不是 if name 处运行 main 函数,然后将其导入脚本并运行。

if __name__=='__main__':
     pass
else:
     main()

【讨论】:

我尝试了你的建议,但现在我认为 Trial.py 的主要功能没有运行,因为我没有看到任何输出。【参考方案2】:

由于您是单独导入模块 print_all,您可以调用 print_all.main()。

更新:我刚刚查看了模块 print_all.py。第一个参数将被假定为文件本身的名称 (print_all)。所以updates.gz 必须是第二个参数。还要确保你使用引号,因为你传递的是一个字符串。

所以你的代码将是:

from mrtparse import *
import gzip
import print_all   
import os
from urllib2 import urlopen, URLError, HTTPError

def fn1():
Bla Bla

def fn2():
    Bla Bla

def main():
    print_all.main('print_all.py updates.gz')

if __name__ == '__main__':
    main()

【讨论】:

它给了我以下错误:TypeError: main() 没有参数(1 个给定)【参考方案3】:

我想,你应该使用:

# ...

import print_all

# ...

def main():
    print_all.main("updates.gz") 

老实说,print_all — 不是一个模块,你不能从任何地方导入它。请注意,examples 文件夹中没有 __init__.py。 否则,您将能够使用mrtparse.examples.print_all。 但是现在mrtparseexamples 中看不到任何内容。

所以,您可以将print_all-script 放在您的脚本附近,然后像我上面显示的那样使用它。

之后

print_all 中的主函数没有参数。 它从命令行参数获取数据。

我认为,你有两种方法:

错误——补丁sys.argv; 正确 — 从 print_all 重写 main。

修补 sys.argv(不好的方式)

import sys
sys.argv = sys.argv = [sys.argv[0], 'updates.gz']

# ...

import print_all

# ...

def main():
    print_all.main() 

# ...

重写 main()

将此函数发布到print_all 并使用它代替main

def do_work(filename):

    d = Reader(filename)

    # if you want to use 'asdot+' or 'asdot' for AS numbers,
    # comment out either line below.
    # default is 'asplain'.
    #
    # as_repr(AS_REPR['asdot+'])
    # as_repr(AS_REPR['asdot'])
    for m in d:
        m = m.mrt
        print('---------------------------------------------------')
        if m.err == MRT_ERR_C['MRT Header Error']:
            prerror(m)
            continue
        print_mrt(m)

        if m.err == MRT_ERR_C['MRT Data Error']:
            prerror(m)
            continue
        if m.type == MRT_T['TABLE_DUMP']:
            print_td(m)
        elif m.type == MRT_T['TABLE_DUMP_V2']:
            print_td_v2(m)
        elif ( m.type == MRT_T['BGP4MP']
            or m.type == MRT_T['BGP4MP_ET']):
            print_bgp4mp(m)

正确的方式

do_work 放在您自己的模块或代码中的任何其他位置。 之后,例如,您的文件将如下所示:

import sys
from optparse import OptionParser
from datetime import *
from mrtparse import *
from print_all import *
import gzip
import print_all   
import os
from urllib2 import urlopen, URLError, HTTPError


def fn1():
    Bla Bla

def fn2():
    Bla Bla

def do_work(filename):

    d = Reader(filename)

    # if you want to use 'asdot+' or 'asdot' for AS numbers,
    # comment out either line below.
    # default is 'asplain'.
    #
    # as_repr(AS_REPR['asdot+'])
    # as_repr(AS_REPR['asdot'])
    for m in d:
        m = m.mrt
        print('---------------------------------------------------')
        if m.err == MRT_ERR_C['MRT Header Error']:
            prerror(m)
            continue
        print_mrt(m)

        if m.err == MRT_ERR_C['MRT Data Error']:
            prerror(m)
            continue
        if m.type == MRT_T['TABLE_DUMP']:
            print_td(m)
        elif m.type == MRT_T['TABLE_DUMP_V2']:
            print_td_v2(m)
        elif ( m.type == MRT_T['BGP4MP']
            or m.type == MRT_T['BGP4MP_ET']):
            print_bgp4mp(m)


def main():
    do_work('updates.gz') 

if __name__ == '__main__':
    main()

【讨论】:

这行得通。但是 sys.argv 做了什么,因为我需要在循环中调用 print_all.py 以使用不同的 .gz 文件运行它?我可以将它放在 Trial.py 主函数中的某个位置,并且每次迭代都会更改 .gz 文件的名称吗? @AhmedAymanIbrahim 当然,您可以在任何地方更改 sys.argv - 但这是“肮脏的黑客”。请查看我的答案的更新。我建议重写 main,或将 do_work 放入 print_all(或您的脚本)。 工作就像一个魅力!

以上是关于Python - 如何在另一个模块中调用模块的主要功能?的主要内容,如果未能解决你的问题,请参考以下文章

python学习之路

GWT:在另一个模块中调用 RPC 服务

Azure IoT Edge ModuleClient 在另一个模块中调用直接方法

Python基础之函数和模块

指示 Python 在另一个文件夹中查找模块

在另一个 UDF 中调用 UDF