2010-08-02 20 views
5

(मैं अजगर 2.7 का उपयोग कर रहा) अजगर प्रलेखन इंगित करता है कि आप dict builtin करने के लिए एक मानचित्रण पारित कर सकते हैं और इसे कॉपी जाएगा दर्ज की है कि नए dict में मानचित्रण:अजगर एबीसी: बनाम उपवर्गीकरण

http://docs.python.org/library/stdtypes.html#mapping-types-dict

मैं एक वर्ग है कि मानचित्रण एबीसी को लागू करता है, लेकिन यह विफल रहता है:

import collections 
class Mapping(object): 
    def __init__(self, dict={}): self.dict=dict 
    def __iter__(self): return iter(self.dict) 
    def __iter__(self): return iter(self.dict) 
    def __len__(self): return len(self.dict) 
    def __contains__(self, value): return value in self.dict 
    def __getitem__(self, name): return self.dict[name] 

m=Mapping({5:5}) 
dict(m) 
# Traceback (most recent call last): 
# File "<stdin>", line 1, in <module> 
# TypeError: cannot convert dictionary update sequence element #0 to a sequence 
collections.Mapping.register(Mapping) 
dict(m) 
# Traceback (most recent call last): 
# File "<stdin>", line 1, in <module> 
# TypeError: cannot convert dictionary update sequence element #0 to a sequence 

हालांकि, अगर मेरी कक्षा उपवर्गों collections.Mapping तो यह ठीक काम करता है:

import collections 
class Mapping(collections.Mapping): 
    def __init__(self, dict={}): self.dict=dict 
    def __iter__(self): return iter(self.dict) 
    def __iter__(self): return iter(self.dict) 
    def __len__(self): return len(self.dict) 
    def __contains__(self, value): return value in self.dict 
    def __getitem__(self, name): return self.dict[name] 

m=Mapping({5:5}) 
dict(m) 
# {5: 5} 

मैंने सोचा कि एबीसी का पूरा बिंदु पंजीकरण को उपclassing (वैसे भी जारी रखने और जारी करने के लिए) के समान काम करने की अनुमति देना था। तो यहाँ क्या हो रहा है?

उत्तर

7

पंजीकरण आपको परिभाषित करने वालों के शीर्ष पर लागू "अनुपलब्ध विधियां" नहीं देता है: वास्तव में, पंजीकरण गैर-आक्रामक आपके द्वारा पंजीकृत किए जाने वाले प्रकार के संबंध में है - इसमें कुछ भी नहीं जोड़ा जाता है, कुछ भी नहीं हटा दिया जाता है, कुछ भी नहीं बदला जाता है। यह केवलisinstance और issubclass चेक को प्रभावित करता है: कुछ भी नहीं, कुछ भी कम नहीं।

एबीसी उप-वर्गीकरण कर सकते हैं और आपको एबीसी द्वारा "मुक्त करने के लिए" बहुत से तरीकों को लागू कर सकते हैं, जिन्हें आप स्वयं परिभाषित कर रहे हैं।

एक ऑपरेशन के अर्थशास्त्र जो एक ऑपरेशन की तुलना में पूरी तरह से गैर-आक्रामक है, वर्ग वर्ग को समृद्ध करने के लिए इच्छित है, स्पष्ट रूप से समान नहीं हो सकता है; इसलिए "एबीसी के पूरे बिंदु" की आपकी समझ अपूर्ण है - एबीसी के पास दो अंक हैं, जो उप-वर्गीकरण ("आक्रामक") द्वारा प्राप्त किए गए हैं, एक पंजीकरण (गैर-आक्रामक) द्वारा प्राप्त किया जाता है।

ध्यान दें कि आप हमेशा गुणा-वारिस कर सकते हैं अगर आप पहले से ही की तरह एक वर्ग है अपने मूल Mapping: class GoogMapping(Mapping, collections.Mapping): ... आप Mapping सीधे इनहेरिट collections.Mapping से रूप में एक ही परिणाम देगा - सभी सहायक विधियों द्वारा जोड़े गए एक नए प्रकार collections.Mapping

+0

धन्यवाद! वह जानकारीपूर्ण था। मैं उपclass नहीं करना चाहता था क्योंकि मैं नहीं चाहता कि जब आप subclass करते हैं तो विशेष "मुक्त" विधियां प्राप्त होंगी। मैंने सोचा कि मैंने अपनी कक्षा को इतना कवर किया था कि मैं इसे एक ताना में डाल सकता हूं, लेकिन मैं गलत था। एक बार फिर धन्यवाद। –

+0

@ एरिक, आपका स्वागत है! आपकी कक्षा के एक उदाहरण w/एक उदाहरण को इमिटिंग (या अपडेट करने) के उद्देश्य से मिसने वाली विशिष्ट विधि 'कुंजी' है - http://svn.python.org/view/python/trunk/Objects की सीएफआर लाइन 1411 /dictobject.c?annotate=81029 - 'if (PyObject_HasAttrString (arg," keys ")) '- इस तरह' dict' पता चलता है कि यह मैपिंग या जोड़े के पुनरावृत्त को पारित किया जा रहा है (पूर्व मामले में, लाइन 1567 , फिर यह 'PyMapping_Keys' और c) का उपयोग करेगा। बीटीडब्ल्यू, निर्दोष लेकिन अनावश्यक, आपने दो बार '__iter__' परिभाषित किया। –

+0

जहां तक ​​मैपिंग क्लास जाता है, क्या इसका मतलब यह है कि उचित मैपिंग में मैपिंग के सभी तरीकों, यहां तक ​​कि मुक्त लोगों के लिए भी होना चाहिए? मैं हाँ सोचूंगा, चूंकि कुंजियों के लिए चाबियाँ अपेक्षित थीं। या यह है कि कुंजी चाबियाँ पाने के लिए इस्तेमाल किया जा सकता था? –

0

आह, ऐसा लगता है जैसे dict() चाबियाँ विधि की तलाश में है ... यह एबीसी का उपयोग नहीं करता है।

+0

यह ('PyMapping_Keys' विशेष रूप से) करता है लेकिन यदि केवल और केवल 'कुंजी' विधि मौजूद है, तो अधिक जानकारी के बारे में ऊपर मेरी टिप्पणी (मेरे ए के टिप्पणियों धागे में) देखें। –

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