2011-05-08 6 views
42

में क्लास ऑब्जेक्ट से नया उदाहरण कैसे बनाएं I मुझे गतिशील रूप से पायथन में कक्षा का उदाहरण बनाने की आवश्यकता है। असल में मैं load_module का उपयोग कर रहा हूं और क्लास को क्लास ऑब्जेक्ट में आयात और लोड करने के लिए मॉड्यूल का निरीक्षण करता हूं, लेकिन मैं यह समझ नहीं सकता कि इस क्लास ऑब्जेक्ट का उदाहरण कैसे बनाया जाए।पायथन

कृपया मदद करें!

ClassName = type("ClassName", (Base1, Base2,...), classdictionary) 

अद्यतन के रूप में टिप्पणी में कहा गया है bellow इस सब पर इस सवाल का जवाब नहीं है:

+5

क्या? 'उदाहरण = कक्षा()' ... –

+0

मुझे लगता है कि आप गतिशील रूप से एक नई कक्षा बनाना चाहते हैं। किसी दिए गए वर्ग की वस्तु नहीं। – jsbueno

+0

नया उदाहरण स्मृति में अपनी जगह के साथ एक नई वस्तु का मतलब है। अधिकांश भाषाएं 'नया' कीवर्ड का उपयोग करती हैं ताकि यह स्पष्ट हो कि ऑब्जेक्ट नया है और नए इंस्टेंस (ऑब्जेक्ट) गुणों को किसी अन्य उदाहरण के साथ संदर्भित/साझा नहीं किया गया है। – BillR

उत्तर

12

बस "प्रकार" तीन मापदंडों का उपयोग कर, इस तरह में बनाया कहते हैं। मैं इसे अवांछित रखूंगा, क्योंकि संकेत हैं कि कुछ लोग यहां गतिशील रूप से कक्षाएं बनाने की कोशिश कर रहे हैं - जो ऊपर की रेखा है।

एक वर्ग एक की एक वस्तु बनाने के लिए एक संदर्भ भी, के रूप में स्वीकार किए जाते हैं जवाब में डाल दिया, एक बस वर्ग कॉल करनी होगी गया है:

instance = ClassObject() 

इन्स्टेन्शियशन के लिए तंत्र इस प्रकार है:

इसकी क्लास ': बजाय इसे डाटा मॉडल एक वर्ग का एक instantance जब यह किसी अन्य प्रतिदेय रूप में एक ही वाक्य रचना के साथ कहा जाता है बनाने के लिए इस्तेमाल तंत्र बताते है - अजगर new कीवर्ड कुछ भाषाओं का उपयोग का उपयोग नहीं करताविधि लागू की जाती है (कक्षा के मामले में, इसकी कक्षा "मेटाक्लास" है - जो आमतौर पर type अंतर्निहित है)। इस कॉल का सामान्य व्यवहार कक्षा (तत्काल) स्थिर __new__ विधि को तत्काल कक्षा में विधि का आह्वान करना है, इसके बाद __init__ है। __new__ विधि स्मृति आवंटित करने के लिए ज़िम्मेदार है और इस तरह, और आमतौर पर __new__object द्वारा किया जाता है जो वर्ग पदानुक्रम रूट है।

तो बुला ClassObject() invokes ClassObject.__class__.call() (जो आम तौर type.__call__ हो जाएगा) इस __call__ विधि ClassObject ही पहले पैरामीटर के रूप में प्राप्त होगा - एक शुद्ध अजगर कार्यान्वयन इस तरह होगा: (CPython संस्करण, निश्चित रूप से है सी में किया, और cornercases के लिए अतिरिक्त कोड के बहुत सारे और अनुकूलन) के साथ

class type: 
    ... 
    def __call__(cls, *args, **kw): 
      constructor = getattr(cls, "__new__") 
      instance = constructor(cls) if constructor is object.__new__ else constructor(cls, *args, **kw) 
      instance.__init__(cls, *args, **kw) 
      return instance 

जड़ __new__ लिए अतिरिक्त पैरामीटर को दबा और अन्य वर्गों के लिए यह पारित करने के लिए (मैं डॉक्स पर देखकर याद नहीं है सही औचित्य (या तंत्र) - लेकिन यह "वास्तविक जीवन में" होता है - यदि object.__new__ किसी भी अतिरिक्त पैरामीट के साथ बुलाया जाता है यह मानते हुए कि Parent पहले से मौजूद है हालांकि, एक __new__ के किसी भी कस्टम कार्यान्वयन सामान्य रूप से अतिरिक्त पैरामीटर)

+6

क्या ओपी एक उदाहरण नहीं बनाना चाहता था, कक्षा नहीं? – Keith

3

इस तरह आप गतिशील रूप से एक वर्ग अपने कोड में Child नामित बना सकते हैं मिल जाएगा, ... भले ही - ईआरएस यह एक प्रकार की त्रुटि को जन्म देती है आपके पास Parent वर्ग नहीं है, तो आप object का उपयोग कर सकते हैं ...

नीचे दिया गया कोड __init__() परिभाषित करता है और फिर इसे कक्षा के साथ जोड़ता है।

>>> child_name = "Child" 
>>> child_parents = (Parent,) 
>>> child body = """ 
def __init__(self, arg1): 
    # Initialization for the Child class 
    self.foo = do_something(arg1) 
""" 
>>> child_dict = {} 
>>> exec(child_body, globals(), child_dict) 
>>> childobj = type(child_name, child_parents, child_dict) 
>>> childobj.__name__ 
'Child' 
>>> childobj.__bases__ 
(<type 'object'>,) 
>>> # Instantiating the new Child object... 
>>> childinst = childobj() 
>>> childinst 
<__main__.Child object at 0x1c91710> 
>>> 
76

मैंने इस प्रश्न का उत्तर निकाला जो मुझे इस पृष्ठ पर लाया था। चूंकि किसी ने वास्तव में मेरे प्रश्न का उत्तर नहीं दिया है, मैंने सोचा कि मैं इसे पोस्ट करूंगा।

class k: 
    pass 

a = k() 
k2 = a.__class__ 
a2 = k2() 

इस बिंदु पर, ए और ए 2 एक ही कक्षा (कक्षा के) के दोनों उदाहरण हैं।

+1

यह सही जवाब प्रतीत होता है। काम करता है और यह आसान है। –

+0

ध्यान दें कि आप कन्स्ट्रक्टर को पैरामीटर भी पास कर सकते हैं, यदि __init__ उन्हें 'a3 = k2 (7)' – gerardw

+0

स्वीकार करता है 'k2 = a .__ class__' और 'k2 = k' के बीच क्या अंतर है? –

2

यदि आपके पास एक कक्षा के साथ एक मॉड्यूल है जिसे आप आयात करना चाहते हैं, तो आप इसे ऐसा कर सकते हैं।

module = __import__(filename) 
instance = module.MyClass() 

यदि आपको नहीं पता कि कक्षा का नाम क्या है, तो आप मॉड्यूल से उपलब्ध कक्षाओं के माध्यम से पुन: प्रयास कर सकते हैं।

import inspect 
module = __import__(filename) 
for c in module.__dict__.values(): 
    if inspect.isclass(c): 
     # You may need do some additional checking to ensure 
     # it's the class you want 
     instance = c()