2012-09-17 19 views
7

Sto lavorando con un framework Python 2.x e una versione recente del framework ha spostato alcune classi di base ampiamente utilizzate dal modulo A al modulo B (e le classi sono stati rinominati con nomi più chiari nel processo). Il modulo A definisce un identificatore compatibile con le versioni precedenti per i nuovi nomi di classe.Uso obsoleto di una classe come classe genitore in Python

B.py:

class BaseClass(object): 
    __metaclass__ = framework_meta # handles registration etc. 

A.py:

import B 
oldbase = B.BaseClass 

Ora, al fine di aiutare le persone a migrare il loro codice, vorrei essere in grado di emettere un DeprecationWarning (utilizzando avvertimenti. warn) ogni volta che il codice che usa il framework definisce una classe derivante da A.oldbase che dice al programmatore di ereditare direttamente da B.BaseClass.

Mi aspetto che questo possa essere ottenuto con un metaclasse. Ho cercato di dichiarare un nuovo metaclasse derivante dalla metaclasse quadro

class deprecated_base_class(framework_meta): 
    def __new__(meta, name, bases, attrs): 
     warning = '%(class)s is deprecated' 
     for b in bases: 
      warning = getattr(b, '__deprecation_warning__', None) or warning 
     warn(warning % {'class': name}, DeprecationWarning, stacklevel=2) 
     return super(deprecated_base_class, meta).__new__(meta, name, bases, attrs) 

insieme:

A.py:

class oldbase(B.BaseClass): 
    __metaclass__ = deprecated_base_class 
    __deprecation_warning__ = 'class oldbase is deprecated. Use B.BaseClass instead' 

clientcode.py

class FooBar(oldbase): 
    pass 

Il problema che ho ora, è che ottengo un DeprecationWarning per la definizione di oldbase. Come posso risolvere questo?

risposta

2

si desidera visualizzare l'avviso se una delle basi sono obsoleti:

class deprecated_base_class(framework_meta): 
    def __new__(meta, name, bases, attrs): 
     for b in bases: 
      if isinstance(b, deprecated_base_class): 
       warning = getattr(b, '__deprecation_warning__', '%(class)s is deprecated') 
       warn(warning % {'class': b.__name__}, DeprecationWarning, stacklevel=2) 
     return super(deprecated_base_class, meta).__new__(meta, name, bases, attrs) 
Problemi correlati