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
。
但是现在mrtparse
在examples
中看不到任何内容。
所以,您可以将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 - 如何在另一个模块中调用模块的主要功能?的主要内容,如果未能解决你的问题,请参考以下文章