यह बिट कोड आपको गतिशील नाम और पैरामीटर नाम के साथ नई कक्षाएं बनाने की अनुमति देता है। __init__
बस में पैरामीटर सत्यापन अज्ञात मापदंडों की अनुमति नहीं देता है, यदि आपको अन्य सत्यापन की आवश्यकता है, जैसे प्रकार, या वे अनिवार्य हैं, तो बस तर्क जोड़ें:
class BaseClass(object):
def __init__(self, classtype):
self._type = classtype
def ClassFactory(name, argnames, BaseClass=BaseClass):
def __init__(self, **kwargs):
for key, value in kwargs.items():
# here, the argnames variable is the one passed to the
# ClassFactory call
if key not in argnames:
raise TypeError("Argument %s not valid for %s"
% (key, self.__class__.__name__))
setattr(self, key, value)
BaseClass.__init__(self, name[:-len("Class")])
newclass = type(name, (BaseClass,),{"__init__": __init__})
return newclass
और यह इस तरह काम करता है, उदाहरण के लिए:
>>> SpecialClass = ClassFactory("SpecialClass", "a b c".split())
>>> s = SpecialClass(a=2)
>>> s.a
2
>>> s2 = SpecialClass(d=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __init__
TypeError: Argument d not valid for SpecialClass
मैं देखता हूं कि आप नामकरण के दायरे में गतिशील नाम डालने के लिए कह रहे हैं - अब, जिसे पायथन में एक अच्छा अभ्यास नहीं माना जाता है - आपके पास या तो चर नाम हैं, जिन्हें कोडिंग समय पर जाना जाता है, या डेटा - और रनटाइम में सीखे गए नाम अधिक हैं " "वैरिएबल" की तुलना में डेटा -
इसलिए, आप अपनी कक्षाओं को एक शब्दकोश में जोड़ सकते हैं और वहां से उनका उपयोग कर सकते हैं:
name = "SpecialClass"
classes = {}
classes[name] = ClassFactory(name, params)
instance = classes[name](...)
और अगर आपके डिज़ाइन को पूरी तरह से नामों की आवश्यकता है, तो बस गुंजाइश करें, लेकिन globals()
एक मनमाने तरीके के बजाय कॉल द्वारा लौटाए गए शब्दकोश का उपयोग करें:
name = "SpecialClass"
globals()[name] = ClassFactory(name, params)
instance = SpecialClass(...)
(यह वास्तव में संभव है कि क्लास फैक्ट्री फ़ंक्शन के लिए कॉलर के वैश्विक दायरे पर नाम सम्मिलित किया जाए - लेकिन यह और भी बुरा अभ्यास है, और पायथन कार्यान्वयन के अनुकूल नहीं है। ऐसा करने का तरीका कॉलर को प्राप्त करना होगा। निष्पादन फ्रेम, sys._getframe (1) के माध्यम से और फ्रेम का वैश्विक शब्दकोश में इसकी f_globals
विशेषता में वर्ग नाम सेट करना )।
अद्यतन, टीएल; डॉ: यह उत्तर लोकप्रिय हो गया था, फिर भी यह प्रश्न निकाय के लिए बहुत विशिष्ट है।
पायथन में "गतिशील रूप से व्युत्पन्न वर्गों को आधार वर्ग से कैसे बनाएं" पर सामान्य उत्तर
type
नए वर्ग के नाम को पारित करने के लिए एक सरल कॉल है , बेसकलैस के साथ एक ट्यूपल (एस) और __dict__
नए वर्ग के लिए शरीर इस तरह:
>>> new_class = type("NewClassName", (BaseClass,), {"new_method": lambda self: ...})
अद्यतन
किसी को भी इसकी आवश्यकता है, इसे डिल प्रोजेक्ट की भी जांच करनी चाहिए - यह दावा करता है कि अचार और अनपैकल वर्ग को साधारण वस्तुओं की तरह ही अचार बनाने में सक्षम है, और मेरे कुछ परीक्षणों में यह रहता था।
a
यह हमेशा रहेगाMyClass
औरTestClass
कभी नहीं लेगाa
? क्यों नहीं सभी 3 तर्कों की घोषणा करते हैं,BaseClass.__init__()
लेकिन उन सभी को डिफ़ॉल्ट रूप सेNone
?def __init__(self, a=None, b=None, C=None)
?