2013-04-23 11 views
8

Ho scritto un metaclasse che sto utilizzando per scopi di registrazione nel mio progetto python. Fa in modo che ogni classe registri automaticamente tutte le attività. L'unico problema è che io non voglio entrare in ogni file e devono aggiungere:Python: impostazione del metaclasse per tutti i file in una cartella

__metaclass__ = myMeta 

C'è un modo per impostare il metaclasse nella cartella di livello superiore in modo che tutti i file sotto l'uso che metaclasse ?

+0

@slashdottir: ecco, risposta aggiornata per coprire 2.7. È ancora un altro hack. –

risposta

6

No, è possibile specificare solo il metaclasse per classe o per modulo. Non puoi impostarlo per l'intero pacchetto.

In Python 3.1 e poi, è possibile intercettare il gancio builtins.__build_class__ e inserire un metaclasse programatically, vedi Overriding the default type() metaclass before Python runs.

In Python 2.7, è possibile sostituire __builtins__.object con una sottoclasse che utilizza la metaclasse. Come il gancio builtins.__build_class__, questo è hackery avanzato e infrange il codice tanto quanto ottenere il metacless in qualsiasi posto.

fare in modo, sostituendo il riferimento object sul __builtin__ module:

import __builtin__ 


class MetaClass(type): 
    def __new__(mcls, name, *args): 
     # do something in the metaclass 
     return super(MetaClass, mcls).__new__(mcls, name, *args) 


orig_object = __builtin__.orig_object 


class metaobject(orig_object): 
    __metaclass__ = MetaClass 


def enable(): 
    # *replace* object with one that uses your metaclass 
    __builtin__.object = metaobject 

def disable(): 
    __builtin__.object = orig_object 

Run enable() questo prima di importare il vostro pacchetto e tutte le classi di nuovo stile (quelle che può sostenere un metaclasse) avrà il vostro metaclasse. Tieni presente che questo comportamento si propagherà a a tutti i codici Python non ancora caricati, inclusa la libreria standard, poiché il pacchetto importa il codice. Probabilmente vuoi usare:

enable() 
import package 
disable() 

per limitare gli effetti.

+0

fantastico! Ci proverò. grazie! – slashdottir

1

Ecco una semplice tecnica. Solo sottoclasse la classe con attributo __metaclass__ nella sottoclasse. Questo processo può essere automatizzato.

util.py

class A(object): 
    def __init__(self, first, second): 
     self.first = first 
     self.second = second 

    def __str__(self): 
     return '{} {}'.format(self.first, self.second) 

main.py

from datetime import datetime 
from util import A 

def meta(*args): 
    cls = type(*args) 
    setattr(cls, 'created', datetime.now().ctime()) 
    return cls 

try: 
    print(A.created) 
except AttributeError as e: 
    print(e) 

class A(A): 
    __metaclass__ = meta 

print(A.created, str(A('Michael', 'Jackson'))) 

di prova;

$ python main.py 
type object 'A' has no attribute 'created' 
('Wed Mar 9 22:58:16 2016', 'Michael Jackson') 
Problemi correlati