我有一堆长pyqt脚本,其中原作者编写了这样的代码
from PyQt4.QtGui import *
from PyQt4.QtCore import *
...
是否有智能或快捷的方式将代码更改为
from PyQt4 import QtGui,QtCore
...
并为每个pyqt类添加模块名称前缀?例如
使用sublime编辑器或pycharm将QDialog
更改为QtGui.QDialog
?或任何其他编辑?
我读到可以为2to3脚本添加自定义修复程序,并为此重新使用该工具,但这似乎不是一项简单的任务。或者建造树木并自己做替换(声音更复杂,也许它正在重新发明轮子)。或者我应该只编写正则表达式替换脚本并解析所有.py文件? (听起来不安全)
编辑:我读了原始问题,似乎我的问题是它的一个子集,最后我使用了一个hacky解决方案,因为我知道我想修复的代码是pyqt。
bad_file = '/path/to/bad_file'
import re
from PyQt4 import QtCore,QtGui
QtCore_mappings = [x for x in dir(QtCore) if '_' not in x]
QtGui_mappings = [x for x in dir(QtGui) if '_' not in x]
mappings = {'QtCore':QtCore_mappings,'QtGui':QtGui_mappings }
cache={}
def find_class_long_name(c):
for k,v in mappings.iteritems():
if c in v:
return '%s.%s' % (k,c)
else:
return None
with open(bad_file) as f:
code = f.read()
all_classes = re.findall(r'\bQ[A-Z]\w*\b', code)
all_classes=set(all_classes)
for c in all_classes:
new_c = find_class_long_name(c)
if new_c:
print '%s ---> %s' % (c, new_c)
code=re.sub(r'\b%s\b' %c,new_c,code)
else:
print 'skipped:',c
# write code to new file
更新2: 我想我可以在不更改代码的情况下替换模块导入行
def find_module(c):
for k,v in mappings.iteritems():
if c in v:
return k
else:
return None
with open(bad_file) as f:
code = f.read()
# print code
all_classes = re.findall(r'\bQ[A-Z]\w*\b', code)
all_classes=set(all_classes)
for c in all_classes:
c_module = find_module(c)
if c_module:
cache[c_module].append(c)
else:
print 'skipped:',c
cmd = ''
for k,v in cache.iteritems():
if cache[k]:
cmd+='from %s import (%s)' % (k, ', '.join(sorted(cache[k])))
cmd+='\n'
print 'new import:\n'
print cmd