2011-04-01 15 views
10

मुझे पता है कि सवाल थोड़ा अजीब बात है, लेकिन मैं इसे कहने के किसी अन्य तरीके के बारे में नहीं सोच सकता। मैं एक आवेदन है कि बड़े json वस्तुओं के साथ संबंधित है, और मैं सिर्फ इतना कहना सक्षम होना चाहते हैं:क्या "डॉट ऑपरेटर ओवरलोड" करने के लिए कोई चाल है?

object1.value.size.whatever.attributexyz 

बजाय

object1.get('value').get('size').get('whatever').get('attributexyz') 

वहाँ कुछ चालाक AttributeError कि उठाया जा जाएगा पकड़ने के लिए रास्ता नहीं है और डेटा संरचना के अंदर जांचें यदि वह विशेषता उसके किसी भी मूल्य से मेल खाती है?

+0

कैसे उन विशेषताओं प्रत्येक वस्तु में जमा हो जाती? यदि वे केवल नियमित सदस्य चर हैं, तो कुछ भी करने के लिए पाइथन में कोई आवश्यकता नहीं है - यह सिर्फ लिखित के रूप में काम करता है। – bgporter

+3

वास्तव में यदि जेसन मॉड्यूल द्वारा जेसन ऑब्जेक्ट वापस किया जाता है तो आपको ऑब्जेक्ट –

+0

ऑब्जेक्ट की मानक पहुंच के लिए 'object1 ['value'] ['size'] ['whatever'] ['attributexyz'] 'करना चाहिए' "डॉट ऑपरेटर" कहें "विशेषता पहुंच"। आप बस "विशेषता पहुंच" को परिभाषित कर रहे हैं। पाइथन ऐसा करने के कई तरीके प्रदान करता है। गुण, सजावट और विशेष विधि नाम। आप प्रश्न शीर्षक बदलना चाहेंगे। –

उत्तर

18

object1 के वर्ग परिभाषा में,

def __getattr__(self, key): 
    return self.get(key) 

एक संपत्ति, विधि, या फ़ील्ड नाम है कि वास्तव में वस्तु ही __getattr__ को दे दिया जाएगा पर मौजूद नहीं है को हल करने का कोई भी प्रयास।

यदि आपके पास कक्षा परिभाषा तक पहुंच नहीं है, यानी यह एक शब्दकोश की तरह कुछ है, इसे कक्षा में लपेटें। एक शब्दकोश के लिए, आप कुछ ऐसा कर सकते हैं:

class DictWrapper(object): 
    def __init__(self, d): 
     self.d = d 
    def __getattr__(self, key): 
     return self.d[key] 

ध्यान दें कि कुंजी अमान्य होने पर एक KeyError उठाया जाएगा; सम्मेलन, हालांकि, एक विशेषता त्रुटि बढ़ाने के लिए है (धन्यवाद, एस लॉट!)। तुम इतनी तरह एक AttributeError रूप KeyError फिर से बढ़ा सकते हैं, यदि आवश्यक हो:

try: 
    return self.get(key) 
except KeyError as e: 
    raise AttributeError(e) 

भी याद रखें कि यदि आप वस्तुओं __getattr__ से लौट रहे हैं भी कर रहे हैं, उदाहरण के लिए, शब्दकोशों, तो आप उन्हें भी रैप करने के लिए की आवश्यकता होगी ।

+2

आप KeyError को छोड़कर 'try: self.get (key) का उपयोग करना चाह सकते हैं: KeyError' से AttributeError() बढ़ाएं। इस तरह एक लापता विशेषता एक उचित विशेषता त्रुटि की रिपोर्ट करता है। –

+0

@ एस। लॉट: बहुत सच; धन्यवाद। –

+0

मुझे त्रुटि मिल रही है। ऐसा लगता है कि 'कोशिश करें: self.d.get (कुंजी) वापस लौटें – yatsa

1

एक ऑब्जेक्ट में संरचना को __getattr__() विधि के साथ लपेटें। यदि आपके पास संरचना पर कोई नियंत्रण है तो आप अपना __getattr___() परिभाषित कर सकते हैं। गेटैटर सिर्फ वही करता है जो आप चाहते हैं - "कैच" गायब गुणों और संभवतः कुछ मूल्य देता है।

0

बस उदाहरण के साथ उपरोक्त उत्तरों को पूरक करने के लिए।

class A: 
    def __init__(self, *args): 
     self.args = args 

    def dump(self, *args): 
     print(self.args, args) 
     return self.args, args 

class Wrap: 
    def __init__(self, c, init_args): 
     self.c, self.init_args = c, init_args 

    def __getattr__(self, key): 
     inst = self.c(*self.init_args) 
     return getattr(inst, key) 

a = Wrap(A, (1, 2, 3)) 
a.dump(4, 5, 6) 

b = Wrap(dict, ({1:2},)) 
print(b.get(1), b.get(3)) 

# This will fail                                                         
print(b[1]) 

आउटपुट,

$ python --version 
Python 3.6.3 
$ python wrap.py 
(1, 2, 3) (4, 5, 6) 
2 None 
Traceback (most recent call last): 
    File "wrap.py", line 24, in <module> 
    print(b[1]) 
TypeError: 'Wrap' object does not support indexing 
संबंधित मुद्दे