2010-04-06 14 views
10

मुझे गतिशील रूप से डेफॉल्ट शब्दकोश से क्लास विशेषताओं को बनाने की आवश्यकता है।गतिशील रूप से कक्षा विशेषताओं को बनाएँ

defaults = { 
    'default_value1':True, 
    'default_value2':True, 
    'default_value3':True, 
} 

class Settings(object): 
    default_value1 = some_complex_init_function(defaults[default_value1], ...) 
    default_value2 = some_complex_init_function(defaults[default_value2], ...) 
    default_value3 = some_complex_init_function(defaults[default_value3], ...) 

मैं भी sth होने से इस हासिल कर सकते हैं। वर्ग निर्माण के लिए __init__ की तरह, गतिशील रूप से शब्दकोश से इन विशेषताओं को बनाने और बहुत सारे कोड और बेवकूफ काम को बचाने के लिए।

आप यह कैसे करेंगे?

अग्रिम में बहुत बहुत धन्यवाद!

उत्तर

3

मुझे लगता है कि metaclass के लिए मामला है:

class SettingsMeta(type): 
    def __new__(cls, name, bases, dct): 
     for name, value in defaults.items(): 
      dct[name] = some_complex_init_function(value, ...) 
     return type.__new__(cls, name, bases, dct) 

class Settings(object): 
    __metaclass__ = SettingsMeta 
+2

हम चूक कैसे पारित करते हैं, या हम @vijayshanker –

+1

एक ही सवाल की किसी भी वस्तु कोड 'defaults' शब्दकोश में किया जा रहा है पर निर्भर करता है कि कैसे प्रारंभ कर सकते हैं: इस तरह के रूप में, आप के साथ ऐसा कर सकते हैं 'सेटिंग्स' कक्षा को परिभाषित करते समय दायरा। – TomSawyer

+0

के साथ इस सेटिंग कक्षा –

19

आप इसे सज्जाकार का उपयोग कर metaclasses बिना कर सकता है। इस तरह थोड़ा और स्पष्ट आईएमओ है:

def apply_defaults(cls): 
    defaults = { 
     'default_value1':True, 
     'default_value2':True, 
     'default_value3':True, 
    } 
    for name, value in defaults.items(): 
     setattr(cls, name, some_complex_init_function(value, ...)) 
    return cls 

@apply_defaults 
class Settings(object): 
    pass 

पायथन 2.6 कक्षा सजावट से पहले अनुपलब्ध थे। तो अगर आप लिख सकते हैं:

class Settings(object): 
    pass 
Settings = apply_defaults(Settings) 

अजगर के पुराने संस्करणों में।

प्रदान की उदाहरण में apply_defaults पुन: प्रयोज्य है ... ठीक है, सिवाय इसके कि चूक हार्ड-कोडेड डेकोरेटर के शरीर में हैं :) तुम सिर्फ एक ही मामला है, तो आप भी इस के लिए अपने कोड को आसान बनाने में कर सकते हैं:

defaults = { 
    'default_value1':True, 
    'default_value2':True, 
    'default_value3':True, 
} 

class Settings(object): 
    """Your implementation goes here as usual""" 

for name, value in defaults.items(): 
    setattr(Settings, name, some_complex_init_function(value, ...)) 

यह संभव है क्योंकि वर्ग (प्रकार की भावना में) पाइथन में स्वयं वस्तुएं हैं।

+1

सजावटी समारोह के अंत में आपको "सजाए गए" वर्ग (पहले उदाहरण में 'cls') वापस करने की भी आवश्यकता है, है ना? मुझे पता लगाने के लिए थोड़ी देर लग गई, लेकिन जब तक मैं ऐसा नहीं करता तब तक कक्षा परिभाषा के बाद 'कोई नहीं' बराबर होगी। क्या मुझे कुछ याद आ रहा है, उदाहरण के लिए संदर्भ के अनुसार कक्षा को आपूर्ति करने का कोई तरीका? – Simon

+0

एक सुरुचिपूर्ण तरीका। – zoujyjs

+0

मैं इस 'ए = सेटिंग्स (डिफ़ॉल्ट)' सेटिंग्स.py' जैसी फ़ाइल में डिफ़ॉल्ट कैसे पास करूं एक विशेष फ़ाइल – TomSawyer

0

कक्षा को परिभाषित करते समय, स्थानीय नामस्थान कक्षा के समापन पर कक्षा नामस्थान में परिवर्तित हो जाएगा।

class Settings(object): 
    for key, val in defaults.iteritems(): 
     locals()[key] = some_complex_init_function(val, ...) 
+1

-1 [दस्तावेज़ीकरण] (http://docs.python.org/library/functions। एचटीएमएल? हाइलाइट = लोकल # लोकल) 'स्थानीय()' के लिए कहता है कि वापस आने वाले शब्दकोश की सामग्री को संशोधित नहीं किया जाना चाहिए। – martineau

+0

यह चालाक है। धन्यवाद। –

संबंधित मुद्दे