type.__setattr__
कक्षाओं के लिए उपयोग किया जाता है, मूल रूप से मेटाक्लास के उदाहरण। दूसरी ओर object.__setattr__
, कक्षाओं के उदाहरणों के लिए प्रयोग किया जाता है। यह पूरी तरह से समझा जाता है।ऑब्जेक्ट से टाइप .__ setattr__ कितना अलग है .__ setattr__?
मैं दो विधि बीच एक महत्वपूर्ण अंतर नहीं दिख रहा है, कम से कम अजगर स्तर पर, मैं नोटिस दो विशेषता काम के लिए एक ही प्रणाली का उपयोग करते है, मुझे ठीक कर लें मैं गलत हूँ:
मान लीजिए a
है उपयोगकर्ता परिभाषित वर्ग का एक उदाहरण, सिर्फ एक सामान्य वर्ग:
class A:
pass
a = A()
a.x = ...
तो a.x = ..
invokes type(a).__setattr__(...)
जो निम्न चरणों का पालन करता है:
नोट: 012,object
builtin वर्ग
1) type(a).__mro__
में एक डेटा वर्णनकर्ता के लिए देखो में __setattr__
मिल जाएगा।
2) यदि कोई डेटा डिस्क्रिप्टर मिला, तो __set__
विधि और बाहर निकलें।
3) कोई डेटा वर्णनकर्ता type(a).__mro__
में पाया गया था, तो विशेषता a.__dict__
को जोड़ने के लिए, a.__dict__['x'] = ...
के साथ कक्षाएं
- metaclasses के उदाहरण, प्रक्रिया समान है:
class A(metaclass=type):
pass
तो : A.x = ...
का अनुवाद type(A).__setattr__(...)
है जो निम्न चरणों का पालन करता है:
नोट: type(A).__setattr__
type
builtin वर्ग
1) type(A).__mro__
2 में एक डेटा वर्णनकर्ता के लिए देखो) यदि एक डेटा वर्णनकर्ता पाया गया था, अपने __set__
विधि और बाहर निकलने फोन में __setattr__
मिल जाएगा।
3) कोई डेटा वर्णनकर्ता type(A).__mro__
में पाया गया था, तो विशेषता A.__dict__
को जोड़ने, a.__dict__['x'] = ...
लेकिन object.__setattr__
वर्गों के लिए काम नहीं करता:
>>> object.__setattr__(A, 'x', ...)
TypeError: can't apply this __setattr__ to type object
और इसके विपरीत, type.__setattr__
नहीं है A
के उदाहरणों के लिए काम:
>>> type.__setattr__(A(), 'x', ...)
TypeError: descriptor '__setattr__' requires a 'type' object but received a 'A'
हमम! दो तरीकों के बीच कुछ अलग होना चाहिए। यह सूक्ष्म है, लेकिन फिर भी सच है!
मुमकिन दो विधियों प्रदर्शन __setattr__
अंदर एक ही कदम, type.__setattr__
और इतने object.__setattr__
के बीच अंतर यह है कि type.__setattr__
वर्गों तक ही सीमित है और object.__setattr__
वर्गों के उदाहरण के लिए सीमित है क्या है?
आपके द्वारा उल्लेखित दूसरे चरण के बारे में एक प्रश्न। आइए मान लें कि 'क्लास' प्रारंभ में '__contains__' के बिना शुरू हुआ था। और कक्षा के निर्माण के बाद '__contains__' असाइन किया गया था। अगर मैं किसी वर्ग को असाइन करता हूं जैसे:' Klass .__ include__ = ... ', 'PyObject_GenericSetAttr'' Klass .__ dict__' और 'update_slot' अपडेट करेगा' __contain__'? इसका मतलब है 'क्लास' के लिए '__contains__' स्लॉट प्रारंभ में' शून्य 'असाइनमेंट से पहले था? – direprobs
@direprobs: 'update_slot'' __contains__' से संबंधित स्लॉट सेट करेगा। वह स्लॉट '-> tp_as_sequence-> sq_contains' है, और केवल 'sq_contains' शून्य से अधिक है, हो सकता है कि यह अभी भी अस्तित्व में न हो, क्योंकि' tp_as_sequence' स्वयं शून्य हो सकता था। (इनमें से कोई भी आपके लिए तब तक महत्वपूर्ण नहीं होना चाहिए जब तक आपको सी एपीआई के साथ काम करने की आवश्यकता न हो।) – user2357112