2009-09-03 9 views
5

मेरे पास एक ऐसा फ़ंक्शन है जो स्ट्रिंग-जैसी तर्क लेता है।पायथन में, स्ट्रिंग-जैसी ऑब्जेक्ट म्यूटेबल होने पर कोई परीक्षण कैसे करता है?

मैं यह तय करना चाहता हूं कि मैं सुरक्षित रूप से तर्क संग्रहीत कर सकता हूं और यह सुनिश्चित कर सकता हूं कि यह नहीं बदलेगा। तो मैं परीक्षण करना चाहता हूं कि यह उत्परिवर्तनीय है, उदाहरण के लिए buffer() का परिणाम array.array() से बनाया गया है, या नहीं।

वर्तमान में मैं का उपयोग करें:

type(s) == str 

वहाँ यह करने के लिए एक बेहतर तरीका है?

(तर्क को कॉपी भी महंगा है, तो इस कारण मैं इसे से बचना चाहते हैं)

+3

मैं आपको अपने प्रश्न का शीर्षक reword सलाह देते हैं। परिभाषा के अनुसार, पायथन में तार ('str' उदाहरण) ** ** ** म्यूटेबल नहीं हैं। स्ट्रिंग की तरह वस्तुओं, हालांकि हो सकता है। –

+1

यह आपके प्रश्न का उत्तर नहीं देता है इसलिए मैं इसे एक टिप्पणी के रूप में पोस्ट कर रहा हूं: आपको प्रकार की तुलना करने के बजाय isinstance (s, basestring) का उपयोग करना चाहिए, इसलिए आप व्युत्पन्न कक्षाओं और यूनिकोड को अस्वीकार नहीं करते हैं। पायथन 3 में, isinstance (एस, str) का उपयोग करें। –

+0

यदि तर्क उत्परिवर्तनीय है तो आप क्या कर रहे हैं? – bstpierre

उत्तर

4

यदि यह आपके कैशिंग के लिए केवल हेरिस्टिक है, तो बस जो भी काम करता है उसका उपयोग करें। Isinstance (एक्स, str), उदाहरण के लिए, लगभग बिल्कुल पसंद है। (आप कैश या नहीं तय करना चाहते हैं को देखते हुए, आप कुछ भी गलत नहीं करते एक झूठी उठाने वाले परीक्षण सिर्फ एक कैश याद आती है इसका मतलब है।)


(टिप्पणी: ऐसा लगता है कि बफर वस्तुओं hashable हैं , भले ही उनके स्ट्रिंग प्रतिनिधित्व अपने पैरों के नीचे बदल सकते हैं;। नीचे हैश चर्चा दिलचस्प है, लेकिन शुद्ध समाधान यह इरादा था नहीं है)

हालांकि, अच्छी तरह से लागू कक्षाओं उदाहरणों अगर वे hashable जा रहा है होना चाहिए अपरिवर्तनीय हैं और नहीं यदि वे उत्परिवर्तनीय हैं। एक सामान्य परीक्षा सफलता के लिए आपकी वस्तु और परीक्षण हैश होगा।

>>> hash({}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: dict objects are unhashable 

इस झूठे सकारात्मक दे देंगे मुझे यकीन है, लेकिन hashable परिवर्तनशील वस्तुओं जा रहा है कड़ाई से एक अंतरफलक को तोड़ने है; मैं अजगर पुस्तकालय प्रकार इस इंटरफेस का पालन की उम्मीद करेंगे, एक छोटा सा नमूना का एक परीक्षण सही जवाब देता है:

hashabe: str (Immutable), buffer (Warning, immutable slice of (possibly) mutable object!) 
unhashable: list, array.array 
+0

यदि आप अपवाद से बचना चाहते हैं, तो आप इसे भी कर सकते हैं: अगर डीआईआर (ओबीजे) और obj .__ हैश__: # सामग्री –

+0

हाँ, ऐसा लगता है कि ऐसा करने का वास्तव में एक बेहतर तरीका नहीं है। मज़े के लिए मैंने समय सारिणी() बनाम प्रकार() और isinstance() धीमा होने पर धीमा है। क्या ऐसा इसलिए है क्योंकि यह आंतरिक रूप से कोशिश/प्रयास करता है? – tonfa

+0

@ kaizer.se: बफर म्यूटेबल है (यदि आप एक array.array से बफर बनाते हैं) – tonfa

3

बस duck typing का उपयोग करें - याद है, यह "माफी से अनुमति के लिए आसान पूछो करने के लिए"। स्ट्रिंग-जैसी ऑब्जेक्ट को म्यूटेट करने का प्रयास करें, और अगर आप नहीं कर सकते तो अपवाद पकड़ने के लिए तैयार रहें।

+3

और महसूस करें कि यह निविड़ अंधकार नहीं है; कोई हमेशा स्ट्रिंग की तरह दिखने वाली ऑब्जेक्ट में गुजर सकता है, लेकिन एक ऐसी विधि है जो प्रभावी रूप से इसके मूल्य को बदल देती है। उदाहरण के लिए, एक स्ट्रिंग-जैसी ऑब्जेक्ट में एक force_upper() विधि हो सकती है जो स्ट्रिंग को स्वयं नहीं बदलती है, लेकिन गेटर्स को अपरकेस डेटा लौटने का कारण बनता है। यदि आपके पास महत्वपूर्ण इनवेरिएंट हैं जो यह जानने पर निर्भर करते हैं कि क्या आप कुछ म्यूटेबल प्राप्त कर रहे हैं, तो इसे दस्तावेज करना सुनिश्चित करें - क्योंकि अधिकांश एपीआई परवाह नहीं है। –

+0

यह सच है, लेकिन ओपी तर्क सुनिश्चित करना चाहता है * संशोधित नहीं किया जाएगा। – bstpierre

+0

विचार अच्छा (और पायथनिक) है, लेकिन यह परीक्षण करना मुश्किल है कि एक ही समय में "unmodified" स्ट्रिंग को रखते हुए उत्परिवर्तन काम करता है ('[0] = एक [0]' खाली स्ट्रिंग के लिए विशेष मामला)। और बीटीडब्ल्यू, अगर आप उठाए जाने के अपवाद को छोड़कर एक कथन से धीमा है तो कोशिश करें/छोड़ दें। – tonfa

5

यह

isinstance(s, basestring) 

यह यूनिकोड स्ट्रिंग्स के लिए भी काम करता है का उपयोग करने के बेहतर होगा।

+0

मुझे यूनिकोड के लिए काम करने की आवश्यकता नहीं है, यह वास्तव में बाइट्स के लिए है (मैं एक वीसीएस पर काम कर रहा हूं)। – tonfa

+0

इसे 'str' के लिए व्युत्पन्न कक्षाओं के लिए काम करने का भी लाभ है। –

+0

यह कोई जवाब नहीं है लेकिन इस तरह टिप्पणी करें इसे एक टिप्पणी के रूप में पोस्ट किया जाना चाहिए। –

3

मैं सिर्फ एक अपरिवर्तनीय स्ट्रिंग के लिए परिवर्तित चाहते हैं:

>>> s1 = "possibly mutable" 
>>> 
>>> s2 = str(s1) 
>>> s1 is s2 
True 

मामले s1 में अपरिवर्तनीय एक ही वस्तु वापस कोई स्मृति भूमि के ऊपर है, जिसके परिणामस्वरूप दिया जाता है, है। यदि यह उत्परिवर्तनीय है तो एक प्रति बनायी जा रही है।

+0

इतनी अच्छी तरह से काम नहीं करता है, तो S1 एक वास्तविक str नहीं है: >>> एस 1 = यू "फू" >>> s2 = str (S1) >>> s2 एस 1 झूठी – bstpierre

+0

है यह नहीं है काम, एक प्रति यहां बहुत महंगा है। – tonfa

+2

क्या आप विस्तार कर सकते हैं कि "एक प्रति यहां बहुत महंगा क्यों है"? यह आपकी समस्या को हल करने के लिए प्राकृतिक पायथनिक तरीका है: यदि आप str() के लिए एक अपरिवर्तनीय स्ट्रिंग पास करते हैं तो यह कुछ भी नहीं करता है, जल्दी से; यदि आप कुछ म्यूटेबल में पास करते हैं, तो आपको एक सुरक्षित अपरिवर्तनीय स्ट्रिंग वापस मिलती है। यह अपर्याप्तता सुनिश्चित करने के लिए आवश्यक न्यूनतम काम करता है। मैं कल्पना करने की कोशिश कर रहा हूं कि यह बहुत महंगा होगा, और मैं इसे अभी तक नहीं देख रहा हूं। – steveha

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