2009-12-22 15 views
28

मैं जानता हूँ कि इस कोड सही है:__getattr__ और getattr के बीच संबंध क्या है?

class A: 
    def __init__(self): 
     self.a = 'a' 
    def method(self): 
     print "method print" 

a = A() 
print getattr(a, 'a', 'default') 
print getattr(a, 'b', 'default') 
print getattr(a, 'method', 'default') 
getattr(a, 'method', 'default')() 


और यह गलत है:

# will __getattr__ affect the getattr? 

class a(object): 
    def __getattr__(self,name): 
     return 'xxx' 

print getattr(a) 

यह भी गलत है:

a={'aa':'aaaa'} 
print getattr(a,'aa') 


हम कहाँ इन कार्यों (__getattr__ और getattr) इस्तेमाल करना चाहिए?

+0

संभावित डुप्लिकेट [\ _ \ _ getattr \ _ \ _ और \ _ \ _ getattribute \ _ \ _] के बीच अंतर को समझना (http://stackoverflow.com/questions/4295678/understanding-the-difference-between- Getattr-and-getattribute) – Trilarion

+1

@Trilarion जो इस प्रश्न के लिए उचित डुप्लिकेट नहीं है –

उत्तर

47

एलेक्स के जवाब अच्छा था, लेकिन एक नमूना कोड के साथ उपलब्ध कराने के बाद से आप यह :) के लिए कहा

class foo: 
    def __init__(self): 
     self.a = "a" 
    def __getattr__(self, attribute): 
     return "You asked for %s, but I'm giving you default" % attribute 


>>> bar = foo() 
>>> bar.a 
'a' 
>>> bar.b 
"You asked for b, but I'm giving you default" 
>>> getattr(bar, "a") 
'a' 
>>> getattr(bar, "b") 
"You asked for b, but I'm giving you default" 
संक्षिप्त उत्तर में

तो

आप को

__getattr__ का उपयोग परिभाषित है गुणों को कैसे प्रबंधित करें

और

getattrकोविशेषताओं

+3

देखें कि क्या आप '__getattr__' का उपयोग करते हैं क्योंकि यह मॉड्यूल में निर्मित 'प्रतिलिपि' को तोड़ देता है जब तक कि आप अपनी कक्षा के लिए' __copy__' और '__deepcopy__' भी लागू नहीं करते। मुझे इस बग का पता लगाने के लिए कुछ समय लगा ... 2.7 वैसे भी –

33

getattr एक अंतर्निहित फ़ंक्शन ले रहा है (कम से कम) दो तर्क: वह ऑब्जेक्ट जिसमें से आप विशेषता प्राप्त कर रहे हैं, और विशेषता का स्ट्रिंग नाम।

तो स्ट्रिंग नाम एक निरंतर है, कहते हैं कि 'foo', getattr(obj, 'foo')बिल्कुल वही बातobj.foo के रूप में है।

तो, अंतर्निहित फ़ंक्शन getattr के लिए मुख्य उपयोग केस तब होता है जब आपके पास स्थिरता के रूप में विशेषता नाम नहीं होता है, बल्कि एक चर के रूप में होता है। एक दूसरा महत्वपूर्ण उपयोग के मामले जब आप इसे तीन तर्कों से पारित है, बल्कि सिर्फ दो से: उस मामले में, अगर विशेषता वस्तु से अनुपस्थित है, getattr तीसरे, "डिफ़ॉल्ट", तर्क है, बजाय एक अपवाद को ऊपर उठाने देता है।

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

तो आपका दूसरा उदाहरण गलत है क्योंकि निर्मित getattrकभी भी को एक भी तर्क के साथ बुलाया नहीं जा सकता है।

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

+2

जबकि आपका उत्तर उत्कृष्ट है, @ zjm1126 एक कोड नमूना चाहता था क्योंकि उसका अंग्रेजी इतना अच्छा नहीं है। – Kimvais

14

__getattr__() एक विशेष विधि समारोह है कि आप को परिभाषित कर सकते है मिलता है। जब कोई सदस्य लुकअप विफल हो जाता है, तो यह फ़ंक्शन कॉल किया जाएगा।

getattr() एक ऐसा फ़ंक्शन है जिसे आप सदस्य लुकअप का प्रयास करने के लिए कॉल कर सकते हैं। यदि लुकअप सफल होता है, तो आप सदस्य (शायद एक विधि फ़ंक्शन ऑब्जेक्ट, या शायद डेटा विशेषता ऑब्जेक्ट) प्राप्त करते हैं। getattr() लुकअप विफल होने के मामले में डिफ़ॉल्ट भी लौटा सकता है।

यदि आप __getattr__() सदस्य फ़ंक्शन घोषित करते हैं, तो आप इसे कभी-कभी सफल बना सकते हैं, या आप इसे हर बार सफल बना सकते हैं।

class A(object): 
    def __getattr__(self, name): 
     return "I pretend I have an attribute called '%s'" % name 

a = A() 

print a.foo # prints "I pretend I have an attribute called 'foo'" 

अजगर भी __getattribute__() जो हमेशा हर देखने पर बुलाया है। यह बहुत खतरनाक है क्योंकि यह आम तौर पर सदस्यों तक पहुंच बनाना असंभव कर सकता है।

class A(object): 
    def __init__(self, value): 
     self.v = value 
    def __getattribute__(self, name): 
     return "I pretend I have an attribute called '%s'" % name 

a = A(42) 

print a.v # prints "I pretend I have an attribute called 'v'" 
print a.__dict__["v"] # prints "I pretend I have an attribute called '__dict__'" 

ओह, अब एवी एक्सेस करना असंभव है!

+1

+1 __getattribute__ का उल्लेख करने के लिए +1 जो मुझे लगता है कि सवाल वास्तव में था। – kibitzer

+0

__getattribute__ का अच्छा और सरल स्पष्टीकरण जो हमेशा मुझे अस्पष्ट लग रहा था। –

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