2013-04-23 10 views
8

मैंने एक मेटाक्लास लिखा है जिसका उपयोग मैं अपने पायथन प्रोजेक्ट में लॉगिंग उद्देश्यों के लिए कर रहा हूं। यह हर वर्ग स्वचालित रूप से सभी गतिविधियों को लॉग करता है। केवल मुद्दा है कि मैं हर फाइल में जाने के लिए और में जोड़ने के लिए नहीं करना चाहती:पायथन: फ़ोल्डर में सभी फ़ाइलों के लिए मेटाक्लास सेट करना

__metaclass__ = myMeta 

वहाँ शीर्ष स्तर फ़ोल्डर में metaclass ताकि स्थापित करने के लिए एक रास्ता है उपयोग के नीचे सभी फ़ाइलें metaclass ?

+0

@ स्लैशडॉटिर: वहां आप जाते हैं, उत्तर 2.7 को अपडेट करने के लिए अपडेट किया गया है। यह अभी तक एक और हैक है। –

उत्तर

6

नहीं, आप प्रति वर्ग या प्रति मॉड्यूल केवल मेटाक्लास निर्दिष्ट कर सकते हैं। आप इसे पूरे पैकेज के लिए सेट नहीं कर सकते हैं।

अजगर 3.1 में और उसके बाद, आप कर सकते हैं अवरोधन builtins.__build_class__ हुक और प्रोग्राम के एक metaclass डालें, Overriding the default type() metaclass before Python runs देखते हैं।

पायथन 2.7 में, आप __builtins__.object को अपने मेटाक्लास का उपयोग करने वाले उप-वर्ग के साथ प्रतिस्थापित कर सकते हैं। builtins.__build_class__ हुक की तरह, यह उन्नत हैकरी है और अपना कोड कहीं भी कहीं भी अपना मेटाक्लास प्राप्त करने के साथ तोड़ दें। अपने पैकेज और सभी नई शैली वर्गों (उन है कि एक metaclass समर्थन कर सकते हैं) का आयात अपने metaclass होगा पहले

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 

भागो enable() इस:

__builtin__ module पर object संदर्भ बदल कर ऐसा करते हैं। ध्यान दें कि यह व्यवहार अब पर प्रचार करेगा सभी मानक लाइब्रेरी समेत पाइथन कोड पहले से लोड नहीं हुआ है, क्योंकि आपका पैकेज आयात कोड करता है। आप शायद उपयोग करना चाहते हैं:

enable() 
import package 
disable() 

प्रभाव को सीमित करने के लिए।

+0

कमाल! मैं कोशिश करने जा रहा हूँ। धन्यवाद! – slashdottir

1

यहां एक साधारण तकनीक है। बस उपclassकक्षा उप-वर्ग में __metaclass__ विशेषता के साथ ही। यह प्रक्रिया स्वचालित हो सकती है।

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'))) 

टेस्ट;

$ python main.py 
type object 'A' has no attribute 'created' 
('Wed Mar 9 22:58:16 2016', 'Michael Jackson') 
संबंधित मुद्दे