यह सामान्य स्थिति के लिए क्या करने के लिए बहुत मुश्किल होगा, लेकिन कुछ व्यावहारिक मामलों के लिए आप कुछ इस तरह कर सकता है:
def call_function_checking_for_modification(f, *args, **kwargs):
myargs = [deepcopy(x) for x in args]
mykwargs = dict((x, deepcopy(kwargs[x])) for x in kwargs)
retval = f(*args, **kwargs)
for arg, myarg in izip(args, myargs):
if arg != myarg:
raise ValueError, 'Argument was modified during function call!'
for kwkey in kwargs:
if kwargs[kwkey] != mykwargs[kwkey]:
raise ValueError, 'Argument was modified during function call!'
return retval
लेकिन, जाहिर है, इस के साथ कुछ मुद्दे हैं। छोटी चीजों के लिए (यानी सभी इनपुट सरल प्रकार होते हैं), फिर भी यह बहुत उपयोगी नहीं है - वे संभावित रूप से अपरिवर्तनीय होंगे, और किसी भी मामले में वे जटिल प्रकारों से तुलना करने के लिए आसान (अच्छी तरह से, अपेक्षाकृत) हैं।
जटिल प्रकारों के लिए, deepcopy
महंगा होगा, और कोई गारंटी नहीं है कि ==
ऑपरेटर वास्तव में सही तरीके से काम करेगा। (और सरल प्रति पर्याप्त नहीं है ... एक सूची की कल्पना करें, जहां एक तत्व मूल्य बदलता है ... एक साधारण प्रति केवल एक संदर्भ संग्रहीत करेगी, और इसलिए मूल मूल्य भी बदल जाएगा)।
सामान्यतः, हालांकि, यह उपयोगी नहीं है, क्योंकि यदि आप पहले से ही इस फ़ंक्शन को कॉल करने के साथ साइड इफेक्ट्स के बारे में चिंतित हैं, तो आप केवल उनके खिलाफ अधिक बुद्धिमानी से रक्षा कर सकते हैं (यदि आवश्यक हो तो अपनी प्रतिलिपि बनाकर, गंतव्य फ़ंक्शन का ऑडिट करना , आदि), और यदि यह आपका कार्य है तो आप साइड इफेक्ट्स के बारे में चिंतित हैं, तो आप इसे सुनिश्चित करने के लिए ऑडिट करेंगे।
उपरोक्त की तरह कुछ सजावट में लपेटा जा सकता है; एक वैश्विक परिवर्तनीय (if _debug == True:
, कुछ ऐसा) द्वारा गठित महंगे हिस्सों के साथ, यह शायद उन परियोजनाओं में उपयोगी हो सकता है जहां बहुत से लोग एक ही कोड को संपादित कर रहे हैं, हालांकि, मुझे लगता है ...
संपादित करें: यह केवल काम करता है उन वातावरणों के लिए जहां 'साइड इफेक्ट्स' का एक और 'सख्त' रूप अपेक्षित है। कई प्रोग्रामिंग भाषाओं में, आप साइड इफेक्ट्स को और अधिक स्पष्ट कर सकते हैं - उदाहरण के लिए सी ++ में, सबकुछ स्पष्ट रूप से एक सूचक या संदर्भ तक मूल्य से होता है, और फिर भी आप इनकमिंग संदर्भों को const
के रूप में घोषित कर सकते हैं ताकि यह नहीं हो सके संशोधित। वहां, 'दुष्प्रभाव' संकलन समय पर त्रुटियों को फेंक सकते हैं। (बेशक कुछ वैसे भी पाने का तरीका है)।
उपरोक्त लागू करता है कि किसी भी संशोधित मान रिटर्न मूल्य/ट्यूपल में हैं। यदि आप अजगर 3 में हैं (मैं अभी तक नहीं हूं) मुझे लगता है कि आप फंक्शन घोषणाओं में विशेषताओं को निर्दिष्ट करने के लिए फ़ंक्शन घोषणाओं में सजावट निर्दिष्ट कर सकते हैं, भले ही उन्हें संशोधित करने की अनुमति दी जाए, और उपरोक्त फ़ंक्शन में अनुमति दें कुछ तर्क स्पष्ट रूप से उत्परिवर्तनीय होने के लिए।
नोट मुझे लगता है कि आप शायद भी कुछ इस तरह कर सकता है:
class ImmutableObject(object):
def __init__(self, inobj):
self._inited = False
self._inobj = inobj
self._inited = True
def __repr__(self):
return self._inobj.__repr__()
def __str__(self):
return self._inobj.__str__()
def __getitem__(self, key):
return ImmutableObject(self._inobj.__getitem__(key))
def __iter__(self):
return self.__iter__()
def __setitem__(self, key, value):
raise AttributeError, 'Object is read-only'
def __getattr__(self, key):
x = getattr(self._inobj, key)
if callable(x):
return x
else:
return ImmutableObject(x)
def __setattr__(self, attr, value):
if attr not in ['_inobj', '_inited'] and self._inited == True:
raise AttributeError, 'Object is read-only'
object.__setattr__(self, attr, value)
(शायद नहीं एक पूर्ण कार्यान्वयन, बहुत परीक्षण नहीं किया है, लेकिन एक शुरुआत)। इस तरह काम करता है:
a = [1,2,3]
b = [a,3,4,5]
print c
[[1, 2, 3], 3, 4, 5]
c[0][1:] = [7,8]
AttributeError: Object is read-only
यह आप संशोधन से एक विशिष्ट वस्तु की रक्षा करता है, तो आप, नीचे की ओर समारोह पर भरोसा नहीं था, जबकि अभी भी अपेक्षाकृत हल्के जा रहा है दिया जाएगा। हालांकि वस्तु के स्पष्ट लपेटने की आवश्यकता है। सभी तर्कों के लिए आप संभवत: अर्द्ध स्वचालित रूप से ऐसा करने के लिए एक सजावटी बना सकते हैं। कॉल करने योग्य लोगों को छोड़ना सुनिश्चित करें।
मुझे नहीं लगता कि आप यह कर सकते हैं। कुछ हद तक संबंधित पोस्ट: http://stackoverflow.com/a/17292194/1967396 – Floris
आप संभवतः साइड-इफेक्ट का पता कैसे लगाएंगे? साइड इफेक्ट और सिर्फ एक प्रभाव के बीच का अंतर काफी शुद्ध रूप से प्रासंगिक है। आप एक ऐसी प्रणाली तैयार करने के लिए भी शुरू कैसे करेंगे जो स्वचालित रूप से ऐसी चीज़ निर्धारित करेगी? –
@ सिलास: सीएस में साइड इफेक्ट का एक बहुत सटीक अर्थ है: वास्तव में वापसी मूल्य के अलावा कुछ भी, http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29 – Junuxx