【发布时间】:2017-06-18 01:45:51
【问题描述】:
我必须将遗留代码(~60K LOC)从 Python 2 移植到 Python 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写回修改后的代码。但这并不简单。 - 如果没有其他方法,我将考虑编写一个简单的 Shell/Python 脚本,该脚本将读取源文件、进行更改并将其写回。
能否有另一种快速简单的方法来处理此更改。
【问题讨论】:
-
Metaclasses have changed in Python 3,
__metaclass__不再起作用。您还可以用一个通用元类替换元类(此处每个类一个),并使用应该适用于所有类的lambda cls, inst: inst in cls.__slots__)。 -
您也可以将
__init__中的代码替换为for slot in __slots__: setattr(self, slot, slot)
标签: python python-3.x sed slots python-2to3