【问题标题】:Python - How to call the main fuction of a module in another module?Python - 如何在另一个模块中调用模块的主要功能?
【发布时间】: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()

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

【问题讨论】:

    标签: python import arguments 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(或您的脚本)。
    • 工作就像一个魅力!
    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多