2016-02-10 26 views
9

के बीच "डीआईआर" में अंतर निम्नलिखित कोड पायथन 2 और पायथन 3 में अलग-अलग व्यवहार करता है, और मुझे यकीन नहीं है कि क्यों।पायथन 2 और 3

class Dataset(object): 
    def __getattr__(self, item): 
     if not item in dir(self): 
      print(item) 

a = Dataset() 
a.Hello 

अजगर 3 में परिणाम:

> Hello 

अजगर 2 में परिणाम:

__members__ 
__members__ 
__methods__ 
... 

अनंत तक जब तक एक प्रत्यावर्तन छत तक पहुँच जाता है। "डीआईआर" के व्यवहार में क्या अंतर है?

संपादित करें: और क्या कोई कामकाज है? स्व। dict स्पष्ट विकल्प है लेकिन इसमें ऐसे फ़ंक्शन शामिल नहीं हैं जो मेरे कोड में कोई समस्या हो।

+2

वास्तव में हो सकता है की जरूरत नहीं है, '__getattr __()' [बिल्कुल भी नहीं कहा जाना चाहिए] (https://docs.python.org/2/reference/datamodel.html#object.__getattr__) यदि विशेषता पहले से मौजूद है। – dhke

उत्तर

6

अजगर 2.7 में dir के लिए दस्तावेज़ और 3.5 समान दिखता है - कोई कार्यान्वयन विवरण नहीं है। लेकिन स्पष्ट रूप से, पाइथन 2 में dir() ने __getattr__ को अनंत रिकर्सन के कारण आमंत्रित किया।

हालांकि, दोनों प्रलेखन सेट कहते हैं कि

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

यह सुविधा एक सुविधा होने के बारे में महत्वपूर्ण है।

यदि आप को को dir() का उपयोग करने के बजाय __getattr__ को संशोधित करने के लिए संशोधित करते हैं, तो समस्या दूर हो जाती है।

In [5]: class Dataset(object): 
      def __getattr__(self, item): 
      if not item in self.__dict__: 
       print(item) 
    ...:    

In [6]: a = Dataset() 

In [7]: a.Hello 
Hello 
+1

जब तक मैंने उत्तर – kdopen

+1

AFAIR पोस्ट नहीं किया, तब तक कार्यों के बारे में संपादन नहीं देखा, 'dir()' '__dir__' को देखने का प्रयास करता है। चूंकि वह अस्तित्व में नहीं है, इसलिए '__getattr __()' कहा जाता है। कौन सा कॉल 'डीआईआर() '... – dhke

3

स्रोत कोड की जांच के बिना, मैं नहीं कह सकता क्यों ऐसा होता है (हालांकि मैं कुछ अवधारणा है), लेकिन यहाँ एक बहुत सरल समाधान नहीं है:

class Dataset(object): 
    def __getattr__(self, item): 
     try: 
      super(Dataset, self).__getattr__(item) 
     except AttributeError: 
      print(item) 
1

यह जांचने के लिए कि if not item in dir(self) अंदर def __getattr__

__getattr__ नहीं कहा जा होगा यदि आइटम dir (स्वयं) में सूचीबद्ध है आप अपने कोड

रूप
class Dataset(object): 
    x = 12 
    def __getattr__(self, item): 
     print(item) 

a = Dataset() 
a.Hello # print Hello 
a.x  # return 12 
संबंधित मुद्दे