#! /usr/bin/env python3# pdeps## Find dependencies between a bunch of Python modules.## Usage:# pdeps file1.py file2.py ...## Output:# Four tables separated by lines like '--- Closure ---':# 1) Direct dependencies, listing which module imports which other modules# 2) The inverse of (1)# 3) Indirect dependencies, or the closure of the above# 4) The inverse of (3)## To do:# - command line options to select output type# - option to automatically scan the Python library for referenced modules# - option to limit output to particular modulesimport sysimport reimport os# Main program#def main():args = sys.argv[1:]if not args:print('usage: pdeps file.py file.py ...')return 2#table = {}for arg in args:process(arg, table)#print('--- Uses ---')printresults(table)#print('--- Used By ---')inv = inverse(table)printresults(inv)#print('--- Closure of Uses ---')reach = closure(table)printresults(reach)#print('--- Closure of Used By ---')invreach = inverse(reach)printresults(invreach)#return 0# Compiled regular expressions to search for import statements#m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')m_from = re.compile('^[ \t]*import[ \t]+([^#]+)')# Collect data from one file#def process(filename, table):fp = open(filename, 'r')mod = os.path.basename(filename)if mod[-3:] == '.py':mod = mod[:-3]table[mod] = list = []while 1:line = fp.readline()if not line: breakwhile line[-1:] == '\\':nextline = fp.readline()if not nextline: breakline = line[:-1] + nextlinem_found = m_import.match(line) or m_from.match(line)if m_found:(a, b), (a1, b1) = m_found.regs[:2]else: continuewords = line[a1:b1].split(',')# print '#', line, wordsfor word in words:word = word.strip()if word not in list:list.append(word)fp.close()# Compute closure (this is in fact totally general)#def closure(table):modules = list(table.keys())## Initialize reach with a copy of table#reach = {}for mod in modules:reach[mod] = table[mod][:]## Iterate until no more change#change = 1while change:change = 0for mod in modules:for mo in reach[mod]:if mo in modules:for m in reach[mo]:if m not in reach[mod]:reach[mod].append(m)change = 1#return reach# Invert a table (this is again totally general).# All keys of the original table are made keys of the inverse,# so there may be empty lists in the inverse.#def inverse(table):inv = {}for key in table.keys():if key not in inv:inv[key] = []for item in table[key]:store(inv, item, key)return inv# Store "item" in "dict" under "key".# The dictionary maps keys to lists of items.# If there is no list for the key yet, it is created.#def store(dict, key, item):if key in dict:dict[key].append(item)else:dict[key] = [item]# Tabulate results neatly#def printresults(table):modules = sorted(table.keys())maxlen = 0for mod in modules: maxlen = max(maxlen, len(mod))for mod in modules:list = sorted(table[mod])print(mod.ljust(maxlen), ':', end=' ')if mod in list:print('(*)', end=' ')for ref in list:print(ref, end=' ')print()# Call main and honor exit statusif __name__ == '__main__':try:sys.exit(main())except KeyboardInterrupt:sys.exit(1)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。