2010-11-02 10 views
5

निम्नलिखित मॉड्यूल को देखते हुए:पाइथन निरीक्षण क्यों करता है। यह सोचता है कि एक उदाहरण एक वर्ग है?

class Dummy(dict): 
    def __init__(self, data): 
     for key, value in data.iteritems(): 
      self.__setattr__(key, value) 

    def __getattr__(self, attr): 
     return self.get(attr, None) 
    __setattr__=dict.__setitem__ 
    __delattr__=dict.__delitem__ 


foo=Dummy({"one":1, "two":2}) 

fooinspect.getmembers(..., predicate=inspect.isclass) के आउटपुट में क्यों दिखता है?

$ python2.5 
Python 2.5.2 (r252:60911, Aug 28 2008, 13:13:37) 
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import junk 
>>> import inspect 
>>> inspect.getmembers(junk, predicate=inspect.isclass) 
[('Dummy', <class 'junk.Dummy'>), ('foo', {'two': 2, 'one': 1})] 
>>> inspect.isclass(junk.foo) 
True 

मुझे उम्मीद है कि inspect केवल Dummy लौटाएगा क्योंकि यह मॉड्यूल में एकमात्र क्लास परिभाषा है। जाहिर है, हालांकि, junk.foo निरीक्षण मॉड्यूल की आंखों में एक कक्षा है। ऐसा क्यों है?

उत्तर

10

पायथन v2.7 से पहले, inspect.isclass ने __bases__ विशेषता के साथ कुछ भी मान लिया है विशेषता एक वर्ग होना चाहिए।

Dummy के __getattr__ बनाता Dummy उदाहरणों हर विशेषता (None के एक मूल्य के साथ) दिखाई देते हैं।

इसलिए inspect.isclass, foo एक वर्ग प्रतीत होता है।

नोट: __getattr__ should raiseAttributeError when asked for an attribute it does not know about. (। यह None लौटने से बहुत अलग है)

+1

विशेष रूप से 'AttributeError' की कमी जो वास्तव में शानदार __horrible__ कीड़े का कारण बन जाएगा। – katrielalex

+0

धन्यवाद। आपकी व्याख्या पूरी समझ में आता है। –

4

पहले अगर सभी महान जवाब जॉन-एरिक मैं सिर्फ कुछ सामान जोड़ना चाहते थे:

आप IPython में क्या करता है, तो (क्या एक महान उपकरण):

%psource inspect.isclass 

आप मिल जाएगा:

return isinstance(object, types.ClassType) or hasattr(object, '__bases__') 

जो जॉन-एरिक ने कहा।

लेकिन मैं अनुमान है कि आप अजगर < 2.6 और इस बग पहले से ही तय किया गया था का उपयोग करें, इस python2.7 में inspect.isclass() के कोड है:

return isinstance(object, (type, types.ClassType)) 
+0

उत्कृष्ट बिंदु! मैं * v2.6 स्रोत देख रहा था। मैंने यह इंगित करने के लिए अपना जवाब संपादित किया कि '__bases__' अब v2.7 + में उपयोग नहीं किया गया है। –

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

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