2010-10-15 14 views
8

मैंने थोड़ी देर के लिए पायथन में प्रोग्राम किया है, और हाल ही में काम पर रूबी का उपयोग करना शुरू कर दिया है। भाषाएं बहुत समान हैं। हालांकि, मैं बस रूबी फीचर में आया था कि मुझे नहीं पता कि पायथन में दोहराना कैसे है। यह रूबी की freeze विधि है।पायथन में फ्रीज?

irb(main):001:0> a = [1,2,3] 
=> [1, 2, 3] 
irb(main):002:0> a[1] = 'chicken' 
=> "chicken" 
irb(main):003:0> a.freeze 
=> [1, "chicken", 3] 
irb(main):004:0> a[1] = 'tuna' 
TypeError: can't modify frozen array 
     from (irb):4:in `[]=' 
     from (irb):4 

क्या Python में इसका अनुकरण करने का कोई तरीका है?

संपादित करें: मुझे एहसास हुआ कि मैंने ऐसा लगता है जैसे यह केवल सूचियों के लिए था; रुबी में, freezeObject पर एक विधि है ताकि आप किसी ऑब्जेक्ट को अपरिवर्तनीय बना सकें। इस गड़बड़ी के लिए मुझे माफ़ करें।

+0

'फ्रीजिंग' पुनरावृत्तियों का मूल्य क्या है? –

+0

आप किसी भी मामले में, एकाधिक धागे आदि पर समान होने पर निर्भर कर सकते हैं, और कई जगहों पर संदर्भित वस्तु के बारे में चिंता करने की आवश्यकता नहीं है क्योंकि यह आपके अंतर्गत से नहीं बदलेगा। – kerkeslager

उत्तर

9

तुम हमेशा list उपवर्ग और "स्थिर" ध्वज जो __setitem__ को ब्लॉक कर देगा कुछ भी करने से जोड़ सकते हैं:

class freezablelist(list): 
    def __init__(self,*args,**kwargs): 
     list.__init__(self, *args) 
     self.frozen = kwargs.get('frozen', False) 

    def __setitem__(self, i, y): 
     if self.frozen: 
      raise TypeError("can't modify frozen list") 
     return list.__setitem__(self, i, y) 

    def __setslice__(self, i, j, y): 
     if self.frozen: 
      raise TypeError("can't modify frozen list") 
     return list.__setslice__(self, i, j, y) 

    def freeze(self): 
     self.frozen = True 

    def thaw(self): 
     self.frozen = False 

तो यह के साथ खेल:

>>> from freeze import freezablelist as fl 
>>> a = fl([1,2,3]) 
>>> a[1] = 'chicken' 
>>> a.freeze() 
>>> a[1] = 'tuna' 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "freeze.py", line 10, in __setitem__ 
    raise TypeError("can't modify frozen list") 
TypeError: can't modify frozen list 
>>> a[1:1] = 'tuna' 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "freeze.py", line 16, in __setslice__ 
    raise TypeError("can't modify frozen list") 
TypeError: can't modify frozen list 
>>> 
+0

आह! मैंने '__set__' और' __setitem__' का उपयोग करने के बारे में नहीं सोचा था! अच्छा निर्णय। – kerkeslager

+0

@kerkeslager: तो यह आपके "किसी ऑब्जेक्ट को फ्रीज" समस्या का समाधान कैसे करता है? – SilentGhost

+0

हाँ, यह स्पष्ट रूप से सामान्य नहीं है (लेकिन कुछ भी नहीं है, क्योंकि पाइथन में कोई समकक्ष, सर्वव्यापी तंत्र नहीं है), लेकिन अगर आप उत्परिवर्तित और उत्परिवर्तकों को ओवरराइड करते हैं तो यह किसी भी प्रकार के वर्ग पर लागू होना चाहिए (उदाहरण के लिए '__setitem__',' __setattr__' , '__setslice__') –

11
>>> a = [1,2,3] 
>>> a[1] = 'chicken' 
>>> a 
[1, 'chicken', 3] 
>>> a = tuple(a) 
>>> a[1] = 'tuna' 
Traceback (most recent call last): 
    File "<pyshell#4>", line 1, in <module> 
    a[1] = 'tuna' 
TypeError: 'tuple' object does not support item assignment 

इसके अलावा, सीएफ। set बनाम frozenset, bytearray बनाम bytes

नंबर, तार अपरिवर्तनीय खुद को कर रहे हैं:

>>> a = 4 
>>> id(a) 
505408920 
>>> a = 42  # different object 
>>> id(a) 
505409528 
+0

हम्म। आप रूबी में किसी ऑब्जेक्ट को फ्रीज कर सकते हैं, यह ऑब्जेक्ट पर परिभाषित है। मुझे नहीं लगता कि यह वही है। यद्यपि पर्याप्त हो सकता है। – steenslag

+0

@steenslag: अजगर चरबी रूबी चर से अलग हैं, इसलिए यह वही बात नहीं है। पाइथन में इंटीग्रर्स और स्ट्रिंग्स अपरिवर्तनीय हैं, फ्रीजिंग डिक्ट्स छोटी है, किसी भी अन्य वस्तु के रूप में। – SilentGhost

+3

मुझे tuples के बारे में पता था और मैंने यह स्पष्ट करने के लिए अपना मूल प्रश्न संपादित किया है कि मैं सभी ऑब्जेक्ट के बारे में बात कर रहा हूं। मैं आपके दावे का मुकाबला करता हूं कि किसी ऑब्जेक्ट को फ्रीज करना पायथन में छोटा है। कम से कम यह 'obj.freeze()' के रूप में छोटा नहीं है, जब तक ऐसा कुछ न हो जो मुझे नहीं पता। – kerkeslager

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