4

Python 3.4 に変換する必要がある非常に大きな Python 2.7.6 プロジェクトがあります。2to3 スクリプトを使用しましたが、「メタクラス」の処理が壊れているようです。

コードをフィルタリングして短縮し、問題を特定しました。次のフラグメントは、Python 2.7.6 でうまく機能します。

class Base(object):
    class __metaclass__(type):
        def __new__(cls, classname, bases, dict):
            new = type.__new__(cls, classname, bases, dict)
            new.classname = classname
            print ("Base::__metaclass__::new. Called.")
            return new                 

class Heir(Base):
    class __metaclass__(Base.__metaclass__):
        def __new__(self, *args):
            new = Base.__metaclass__.__new__(self, *args)
            print ("Heir::__metaclass__::new. Called.")
            return new

    @classmethod
    def define(cls, nexttype):
        print ("Heir::define. Called.")

class HeirOfHeir(Heir):
    pass

Heir.define(HeirOfHeir)

コードは期待どおりに出力されます。

Base::__metaclass__::new. Called.
Base::__metaclass__::new. Called.
Heir::__metaclass__::new. Called.
Base::__metaclass__::new. Called.
Heir::__metaclass__::new. Called.
Heir::define. Called.

しかし、Python 3.4 でコードを実行すると、最後の出力しかありません。

Heir::define. Called.

計算が間違っているか2to3、手作業が必要です。残念ながら、メタクラスの経験はほとんどありません。

4

1 に答える 1