2013-02-17 12 views
26

मेरे पास एक वस्तु है "myobject", जो None लौटा सकता है। यह देता है, तो None, यह एक विशेषता "id" नहीं लौटेगा:मैं एक विशेषता के लिए डिफ़ॉल्ट मान कैसे वापस कर सकता हूं?

AttributeError: 'NoneType' object has no attribute 'id' 

तो myobject कोई नहीं है, तो:

a = myobject.id 

तो जब MyObject None, एक AttributeError में परिणामों के ऊपर stament है मैं चाहता हूं कि "a" किसी के बराबर न हो। मैं इस तरह के रूप में एक पंक्ति बयान में इस अपवाद, कैसे बच है:

a= default(myobject.id, None) 

उत्तर

71

आप सीधे id का मूल्य पुन: प्राप्त करने के बजाय getattr आवरण का उपयोग करना चाहिए।

a = getattr(myobject, 'id', None) 

यह कह रही है की तरह है "मैं वस्तु myobject से विशेषता id पुनः प्राप्त करना चाहते हैं, लेकिन अगर कोई वस्तु myobject अंदर कोई गुण id है, तो None लौटने के बजाय।" लेकिन यह कुशलतापूर्वक करता है।

a = myobject.getattr('id', None) 

ओपी अनुरोध के अनुसार, 'deep getattr':

def deepgetattr(obj, attr): 
    """Recurses through an attribute chain to get the ultimate value.""" 
    return reduce(getattr, attr.split('.'), obj) 
# usage: 
print deepgetattr(universe, 'galaxy.solarsystem.planet.name') 

सरल स्पष्टीकरण:

कुछ वस्तुएं भी getattr उपयोग की निम्न प्रपत्र का समर्थन

Reduce एक में जगह की तरह है रिकर्सिव फ़ंक्शन।क्या यह इस मामले में करता है obj (ब्रह्मांड) के साथ शुरू और फिर रिकर्सिवली प्रत्येक विशेषता के लिए आप getattr का उपयोग कर, तो अपने प्रश्न में यह इस तरह किया जाएगा तक पहुँचने का प्रयास गहरी मिलता है:

a = getattr(getattr(myobject, 'id', None), 'number', None)

+1

+1, यह शायद सबसे अच्छा विचार है, मुझे नहीं पता कि मैंने ऐसा क्यों नहीं सोचा। –

+0

हा, धन्यवाद, लापरवाह आत्म प्रचार के लिए आपके समर्थन का उपयोग करने जा रहा है।: पी –

+0

@ इंबर रोज़ और क्या होगा यदि मैं ओब्टा चाहता हूं वैसे ही विशेषता के गुण में, जैसे 'a = myobject.id.number'? – alwbtc

10

सबसे आसान तरीका त्रिगुट ऑपरेटर का उपयोग करने के लिए है:

a = myobject.id if myobject is not None else None 

त्रिगुट ऑपरेटर पहली अभिव्यक्ति देता है, तो मध्यम मान है सच है, अन्यथा यह बाद की अभिव्यक्ति देता है।

ध्यान दें कि आप भी किसी अन्य तरीके से ऐसा कर सकता है, अपवाद का उपयोग कर: - क्या सबसे अच्छा है स्थिति पर निर्भर करेगा

try: 
    a = myobject.id 
except AttributeError: 
    a = None 

यह pythonic आदर्श है कि यह अनुमति से माफी के लिए पूछना आसान है फिट बैठता है।

+0

यह तेजी का मूल्यांकन करता है? मेरे पास इस चेक को करने के लिए 30000 ऑब्जेक्ट हैं। – alwbtc

+0

@alwbtc इसे आज़माएं और देखें। 'टाइमिट' मॉड्यूल देखें। यदि आपको लगता है कि यह बहुत अधिक संभावना है कि मूल्यों का एक बड़ा हिस्सा 'कोई नहीं 'होगा, तो पहला तरीका शायद तेज़ होगा, अन्यथा, दूसरे का उपयोग करें। –

+0

ठीक है, कोई भी मूल्य बहुत अधिक नहीं है। तो मैं दूसरी विधि का उपयोग करूंगा। लेकिन मैं एक लाइनर से युक्त कोड भी चाहता हूं। क्या आपको नहीं लगता कि एक-पंक्ति विवरण बेहतर हैं? – alwbtc

0
try: 
    a = myobject.id 
except AttributeError: 
    a = None 

भी काम करेगा और स्पष्ट है, IMO

+0

मैं "पायथन विशेषज्ञ नहीं हूं, लेकिन अधिकांश भाषाओं में मैं निपटने के लिए उपयोग करता था," छोड़कर "कथन में गिरने के लिए एक अतिरिक्त लागत होती है जो कि पर्याप्त नहीं है। इस तरह के एक साधारण मामले में, मैं" getattr " "दृष्टिकोण (मान लीजिए कि यह कम महंगा है)। क्या आप में से कुछ Getattr विधि के बारे में कुछ और बता सकते हैं? –

+0

समयपूर्व अनुकूलन, अच्छा लड़का, समयपूर्व अनुकूलन – hd1

+2

यह समयपूर्व अनुकूलन नहीं है। सामान्य व्यवहार को संभालने के लिए अपवादों का उपयोग करना सामान्य रूप से खराब शैली माना जाता है – francoisr

1

Help on built-in function getattr in module builtins:

getattr(...) 
    getattr(object, name[, default]) -> value 

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case.

काम करना चाहिए के बाद:

a = getattr(myobject, 'id', None) 
6
मेरी वस्तु वर्ग में

आप ओवरराइड

डाल सकते हैं
class Foo(object): 
    def __getattribute__(self, name): 
     if not name in self; 
     return None; 
     else: 
     # Default behaviour 
     return object.__getattribute__(self, name) 
0

आप (Black Diamond's answer में) की तरह myobject के वर्ग की परिभाषा में समस्या का समाधान चाहते हैं तो आप बस __getattr__None वापस जाने के लिए परिभाषित कर सकते हैं:

class Myobject: 
    def __getattr__(self, name): 
     return None 

यह काम करता है क्योंकि __getattr__ केवल जब कहा जाता है एक विशेषता का उपयोग करने का प्रयास कर रहा है जो मौजूद नहीं है, जबकि __getattribute__ हमेशा विशेषता के नाम से कोई फर्क नहीं पड़ता है। (यह भी this SO post देखें।)

आज़माने के लिए:

myobject = Myobject() 
print myobject.id 
myobject.id = 7 
print myobject.id 
संबंधित मुद्दे

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