У меня есть порт унаследованного кода (~ 60K LOC) из Python 2 до 3, который имеет несколько тысяч структур, как показано ниже:Как порт `__slots__` из 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
для записи измененного кода. Но это не просто. - Если ничего не работает, я рассмотрю возможность написания простого сценария Shell/Python, который будет читать исходный файл, вносить изменения и записывать его обратно.
Может ли быть другой быстрый и простой способ справиться с этим изменением.
[Метаклассы изменились в Python 3] (https://docs.python.org/3/reference/datamodel.html), '__metaclass__' Безразлично Больше не работай. Вы также можете заменить метаклассы (по одному для каждого класса здесь) одним общим метаклассом и использовать 'lambda cls, inst: inst в cls .__ slots __)', который должен работать для всех классов. –
И вы также можете заменить код в '__init__'' на слот в __slots__: setattr (self, slot, slot) ' –