पायथन __getitem__ और ऑपरेटर में अजीब व्यवहार होता है


34

निम्नलिखित व्यवहार की व्याख्या क्या है:

class Foo:
    def __getitem__(self, item):
        print("?")
        return 1

f = Foo()

1 in f  # prints one ? and returns True

5 in f  # prints ? forever until you raise a Keyboard Exception

# Edit: eventually this fails with OverflowError: iter index too large

जवाबों:


45

यदि किसी ऑब्जेक्ट का __contains__कार्यान्वयन नहीं होता है, तो inडिफ़ॉल्ट रूप से वापस आता है जो मूल रूप से इस तरह काम करता है:

def default__contains__(self, element):
    for thing in self:
        if thing == element:
            return True
    return False

और यदि किसी ऑब्जेक्ट का __iter__कार्यान्वयन नहीं होता है, तो forमूल रूप से इस तरह काम करने वाले डिफ़ॉल्ट पर वापस आ जाता है:

def default__iter__(self):
    i = 0
    try:
        while True:
            yield self[i]
            i += 1
    except IndexError:
        pass

इन डिफॉल्ट्स का उपयोग तब भी किया जाता है, जब ऑब्जेक्ट का अनुक्रम होने का इरादा न हो।

आपके 1 in fऔर 5 in fपरीक्षण, डिफॉल्ट व्यवहार के लिए डिफ़ॉल्ट कमियों का उपयोग कर रहे हैं inऔर forआगे बढ़ रहे हैं। तुरंत 1 in fमिल जाता 1है, लेकिन आपका __getitem__कभी नहीं लौटता है 5, इसलिए 5 in fहमेशा के लिए चलता है।

(खैर, वास्तव में, पायथन के संदर्भ कार्यान्वयन पर, डिफ़ॉल्ट __iter__फ़ॉलबैक एक सी-स्तरीय चर में सूचकांक को संग्रहीत करता है Py_ssize_t, इसलिए यदि आप लंबे समय तक प्रतीक्षा करते हैं, तो वह चर अधिकतम हो जाता है और पायथन ओवरफ़्लो हो जाता है । यदि आपने वह देखा है, तो आप। एक 32-बिट पायथन बिल्ड पर होना चाहिए। कंप्यूटर किसी के लिए इतना लंबा अस्तित्व में नहीं है कि 64-बिट पायथन पर हिट हो।)


OverflowError के बारे में, मैंने इसे 64 और 32 बिट दोनों पर चलाया, और आप सही हैं मैंने इसे केवल 32 बिट पर देखा।
— मैथ्यू Moisen

क्या आपको उस दस्तावेज के बारे में पता है जो यह बताता है? मैं इस बारे में पढ़ना चाहूंगा कि यह कार्यान्वयन क्यों तय किया गया था।
— मैथ्यू मोइसन


4
@ मट्टूमोइसेन: ये चूक मूल व्यवहार थे forऔर in, की शुरूआत से पहले __iter__और __contains__। अजगर 1.4 प्रलेखन यहाँ और यहाँ देखें ।
— user2357112
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.