我必须将遗留代码( ~60K LOC)从Python 2移植到3,它有几千个结构,如下所示:
class Sample(object):
__slots__ = ('both', 'advertise')
class __metaclass__(type):
__instancecheck__ = classmethod(
lambda cls, inst: inst in ('both', 'advertise'))
both = 'both'
advertise = 'advertise'这段代码适用于Python 2,但没有用Python 3编译,要解决这个问题,我需要将它更改为
class Sample(object):
__slots__ = ('both', 'advertise')
class __metaclass__(type):
__instancecheck__ = classmethod(
lambda cls, inst: inst in ('both', 'advertise'))
def __init__(self):
both = 'both'
advertise = 'advertise',如果必须多次处理这么大的文件,那么处理此更改的有效方法是什么?
我们必须考虑,对于该类,可能已经有或可能没有__init__函数定义,也可以有嵌套类定义。
到目前为止,这就是我所尝试的。
2to3没有意识到这是一个问题,因此不会改变它。ast模块修改内存中的解析树,然后使用unparse编写修改后的代码。但这并不是简单明了的。还有另一种快速而简单的方法来处理这个更改吗?
发布于 2017-02-01 11:23:19
我不知道有什么比写一个小剧本更好的方法。我认为这些更改足够小,所以您可以使用一些很好的启发式方法,而不需要ast的全部功能。
但是,如果您有这么多重复的代码,我将从您的代码中删除所有的类。您可以用代码生成器或为这些类编写工厂函数来替换它们。这将对您的代码进行将来的验证,以防止任何更改。
这样的工厂可能是这样的:
class HasStringInstances(type):
def __instancecheck__(cls, instance):
return instance in cls.__slots__
def create_special_class(*slots):
class SpecialClass(object, metaclass=HasStringInstances):
__slots__ = slots
def __init__(self):
for slot in self.__slots__:
# assign name as value
setattr(self, slot, slot)
return SpecialClass
Sample = create_special_class('both', 'advertise')https://stackoverflow.com/questions/41977636
复制相似问题