包装 Python cProfile runctx API 以参数化任何地方运行
Wrapping Python cProfile runctx API to parameterize runs with anything anywhere
使用 Python 3.7.2,
我正在尝试将 cProfile.runctx()
包装到一个单独的模块中,例如来自我的主模块 mymain.py
的 util.profile_runs()
以分析主模块中的函数。这需要在 util.profile_runs()
.
中导入 mymain.py
但是,我无法 importlib
使用 util.py
中的以下代码:
import cProfile as profile
import importlib.util
from os.path import basename, splitext
from pprint import pprint
import pstats
import sys
def profile_runs(funcname, modulefile, nruns=5):
importlib.machinery.SOURCE_SUFFIXES.append('')
module_name = splitext(basename(modulefile))[0]
spec = importlib.util.spec_from_file_location(module_name, modulefile)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# if desired: importlib.machinery.SOURCE_SUFFIXES.pop()
pprint(dir(module))
for i in range(nruns):
filename = 'profile_{}_{}.stats'.format(funcname, i)
profile.runctx('print({}, {}.{}())'.format(i, module_name, funcname), globals(), locals(), filename)
# Read all 5 stats files into a single object
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, nruns):
stats.add('profile_{}_{}.stats'.format(funcname, i))
# Clean up filenames for the report
stats.strip_dirs()
# Sort the statistics by the cumulative time spent
# in the function
stats.sort_stats('cumulative')
stats.print_stats()
和mymain.py
:
import util
def func_to_profile()
print('running func_to_profile')
if __name__ == '__main__':
util.profile_runs('funct_to_profile')
pprint(dir(module))
行输出模块的正确信息,但 .runctx
调用一直说:
NameError: name 'mymain' is not defined
如果我在 util.profile_runs()
代码中显式 import mymain
,它就会工作。
以这种方式描述是不是一个坏主意?
我找到了一个解决方法:只需在 运行 字符串中插入 import module_name;
,如下所示:
profile.runctx('import {};print({}, {}.{}())'.format(module_name, i, module_name, funcname), globals(), locals(), filename)
并摆脱整个 importlib
舞蹈。
使用 Python 3.7.2,
我正在尝试将 cProfile.runctx()
包装到一个单独的模块中,例如来自我的主模块 mymain.py
的 util.profile_runs()
以分析主模块中的函数。这需要在 util.profile_runs()
.
mymain.py
但是,我无法 importlib
使用 util.py
中的以下代码:
import cProfile as profile
import importlib.util
from os.path import basename, splitext
from pprint import pprint
import pstats
import sys
def profile_runs(funcname, modulefile, nruns=5):
importlib.machinery.SOURCE_SUFFIXES.append('')
module_name = splitext(basename(modulefile))[0]
spec = importlib.util.spec_from_file_location(module_name, modulefile)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# if desired: importlib.machinery.SOURCE_SUFFIXES.pop()
pprint(dir(module))
for i in range(nruns):
filename = 'profile_{}_{}.stats'.format(funcname, i)
profile.runctx('print({}, {}.{}())'.format(i, module_name, funcname), globals(), locals(), filename)
# Read all 5 stats files into a single object
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, nruns):
stats.add('profile_{}_{}.stats'.format(funcname, i))
# Clean up filenames for the report
stats.strip_dirs()
# Sort the statistics by the cumulative time spent
# in the function
stats.sort_stats('cumulative')
stats.print_stats()
和mymain.py
:
import util
def func_to_profile()
print('running func_to_profile')
if __name__ == '__main__':
util.profile_runs('funct_to_profile')
pprint(dir(module))
行输出模块的正确信息,但 .runctx
调用一直说:
NameError: name 'mymain' is not defined
如果我在 util.profile_runs()
代码中显式 import mymain
,它就会工作。
以这种方式描述是不是一个坏主意?
我找到了一个解决方法:只需在 运行 字符串中插入 import module_name;
,如下所示:
profile.runctx('import {};print({}, {}.{}())'.format(module_name, i, module_name, funcname), globals(), locals(), filename)
并摆脱整个 importlib
舞蹈。