यह ध्यान देने योग्य है कि प्रश्न में विशिष्ट समस्या के लिए, उपयोग करने के लिए कई विकल्प हैं eval
:
सबसे सरल, जैसा कि उल्लेख किया गया है, उपयोग कर रहा है setattr
:
def __init__(self):
for name in attsToStore:
setattr(self, name, None)
एक कम स्पष्ट दृष्टिकोण ऑब्जेक्ट के __dict__
ऑब्जेक्ट को सीधे अपडेट कर रहा है। यदि आप सभी करना चाहते हैं None
, तो विशेषताओं को इनिशियलाइज़ करना है , तो यह ऊपर की तुलना में कम सीधा है। लेकिन इस पर विचार करें:
def __init__(self, **kwargs):
for name in self.attsToStore:
self.__dict__[name] = kwargs.get(name, None)
इससे आप कंस्ट्रक्टर को कीवर्ड तर्क पास कर सकते हैं, जैसे:
s = Song(name='History', artist='The Verve')
यह आपको अपने उपयोग को locals()
और अधिक स्पष्ट करने की अनुमति देता है , जैसे:
s = Song(**locals())
... और, यदि आप वास्तव में None
उन विशेषताओं को निर्दिष्ट करना चाहते हैं जिनके नाम निम्नलिखित हैं locals()
:
s = Song(**dict([(k, None) for k in locals().keys()]))
गुण की सूची के लिए डिफ़ॉल्ट मानों के साथ एक वस्तु प्रदान करने के लिए एक और दृष्टिकोण वर्ग की __getattr__
विधि को परिभाषित करना है :
def __getattr__(self, name):
if name in self.attsToStore:
return None
raise NameError, name
यह विधि तब प्राप्त होती है जब नामित विशेषता सामान्य तरीके से नहीं मिलती है। यह सीधे तौर पर कंस्ट्रक्टर में विशेषताओं को सेट करने या अपडेट करने की तुलना में कुछ कम सीधा है __dict__
, लेकिन इसमें वास्तव में विशेषता के निर्माण की योग्यता नहीं है जब तक कि यह मौजूद नहीं है, जो क्लास की मेमोरी उपयोग को काफी हद तक कम कर सकता है।
इस सब के बिंदु: सामान्य रूप से, बचने के लिए बहुत सारे कारण हैं eval
- कोड को निष्पादित करने की सुरक्षा समस्या जिसे आप नियंत्रित नहीं करते हैं, कोड की व्यावहारिक समस्या जिसे आप डिबग नहीं कर सकते हैं, आदि। लेकिन एक और भी महत्वपूर्ण कारण। यह है कि आम तौर पर, आपको इसका उपयोग करने की आवश्यकता नहीं है। पायथन प्रोग्रामर के लिए अपने आंतरिक तंत्र का इतना विस्तार करता है कि आपको कोड लिखने के लिए वास्तव में कोड लिखने की आवश्यकता नहीं है।
exec/eval
और अभी भी नहीं पता हैsetattr
?