कैसे पता चलेगा कि किसी वस्तु में पायथन में कोई विशेषता है


1631

क्या पायथन में एक तरीका है यह निर्धारित करने के लिए कि किसी वस्तु में कुछ विशेषता है? उदाहरण के लिए:

>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'

यदि आप इसका उपयोग करने से पहले aविशेषता रखते हैं तो आप कैसे बता सकते हैं property?

जवाबों:


2335

कोशिश करें hasattr():

if hasattr(a, 'property'):
    a.property

EDIT: नीचे देखें zweiterlinde का जवाब , जो माफी मांगने के बारे में अच्छी सलाह देता है! एक बहुत ही अजगर दृष्टिकोण!

अजगर में सामान्य प्रथा यह है कि, अगर संपत्ति के अधिकांश समय होने की संभावना है, तो बस इसे कॉल करें और या तो अपवाद का प्रचार करें, या इसे एक कोशिश के साथ फँसाने दें / ब्लॉक को छोड़कर। यह संभवतः की तुलना में तेज़ होगा hasattr। यदि संपत्ति के अधिकांश समय पर नहीं होने की संभावना है, या आप निश्चित नहीं हैं, तो उपयोग hasattrकरना संभवतः अपवाद ब्लॉक में बार-बार गिरने की तुलना में तेजी से होगा।


19
नामस्थान में कार्यों की जाँच के लिए काम करने लगता है, जैसे: import string hasattr(string, "lower")
riviera

15
hasattrका उपयोग कर के रूप में बिल्कुल वैसा ही है try/ except AttributeError: hasattr का डॉकस्ट्रिंग (पायथन 2.7 में) का कहना है कि यह गेटाट्र हैंड कैच अपवादों का उपयोग करता है।
जेफ ट्रटनर 3

8
@JeffTratner: hasattrदुर्भाग्य से पाइथन 2.x में बिल्कुल वैसा नहीं है , try: ... except AttributeError:क्योंकि सभी अपवादोंhasattr को पकड़ लेंगे । कृपया एक उदाहरण और एक सरल समाधान के लिए मेरा उत्तर देखें ।
मार्टिन गिस्लर

1
@MartinGeisler अच्छा बिंदु - यह सभी अपवादों को पकड़ने के समान नहीं है। निश्चित नहीं है कि कौन सा संस्करण अधिक सही है - वास्तव में उन मान्यताओं पर निर्भर करता है, जिनके तहत आप काम कर रहे हैं और जो आपके फ़ंक्शन को कॉल कर रहे हैं। स्पष्टीकरण देने के लिए धन्यवाद।
जेफ ट्रैटनर 25'13

2
hasattrयह भी बेहतर विकल्प है यदि आप एक समझ में हैं, जैसे[a.property for a in list_of_as if hasattr(a, "property")]
राफेल मार्टिंस

631

जैसा कि जेरेट हार्डी ने उत्तर दिया, hasattrचाल चलेगा। मैं जोड़ना चाहूंगा, हालांकि, पायथन समुदाय में कई लोग "अनुमति से पहले क्षमा करने के लिए आसान" (ईएएफपी) के बजाय "आप लीप लेने से पहले देखो" (एलबीवाईएल) की रणनीति की सलाह देते हैं। ये संदर्भ देखें:

ईएएफपी बनाम एलबीवाईएल (पुन: थोड़ा निराश किया गया था)
ईएएफपी बनाम एलबीवाईएल @कोड एक पायथन की तरह: आइडोमेटिक पायथन

अर्थात:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... को प्राथमिकता दी जाती है:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

257
लेकिन आप कैसे जांचते हैं कि यह a.property था जो AttributeError का कारण था, और doStuff () में कुछ नहीं? ऐसा लगता है कि तुम नहीं। मुझे लगता है कि माफी मांगना वास्तव में आसान है, लेकिन कई बार, यह गलत भी है।
१२:२२ पर १२'०

282
ईएएफपी लगता है ... पागल। HasAttr भविष्य के मुख्य प्रोग्रामर को टेलीग्राफ करता है जिसे आप किसी विशेष विशेषता के लिए जाँच रहे हैं। एक अपवाद प्राप्त करना भविष्य के प्रोग्रामर को कुछ नहीं बताता है और किसी को खरगोश के छेद के नीचे ले जा सकता है।
ईथन हेइलमैन

74
@ e5: आपके पास इस मामले में एक उचित बिंदु है, लेकिन कई मामलों में ईएएफपी एकमात्र सही विकल्प है। उदाहरण के लिए, यदि आप किसी फ़ाइल के अस्तित्व की जाँच करते हैं और फिर उसे खोलते हैं, तो यह उम्मीद करते हैं कि वह निश्चित रूप से मौजूद होगी, आपका कोड गलत है: फ़ाइल को चेक और उपयोग के बीच हटा दिया या बदला जा सकता है। इसे TOCTOU त्रुटि (टाइम-टू-चेक-टू-टाइम-ऑफ़-यूज़) कहा जाता है और इसके अलावा क्रैश भी सुरक्षा कमजोरियों का कारण हो सकता है।
मैक्स

15
@ ईथनहिलमैन यह केवल पागल है जब अपवाद के स्रोत में अस्पष्टता होती है, जो कि ज्यादातर मामलों में अच्छे डिजाइन से बचा जा सकता है। कोशिश के अलावा / के भीतर तर्क की अच्छी तरह से स्तरित संरचना / अंत में आम तौर पर अधिक मजबूत (कम प्रोग्रामर त्रुटि प्रवण) तर्क के लिए होता है, जो कोड के प्रीमेप्टिव के साथ कोड को लिट करने की तुलना में होता है, अगर उपभोग कोड के प्रत्येक टुकड़े के लिए। त्रुटियों को बहुत स्पष्ट रूप से स्पष्ट करता है, और खपतकर्ताओं को सीधे उनसे निपटने का विकल्प देता है।
पीटर एम। एलियास

64
यहां ज्यादातर अस्पष्टता की शिकायतें सिर्फ इसलिए हैं क्योंकि नमूना कोड खराब संरचित है। केवल अंदर की चीज try:का प्रयास किया जाना चाहिए विशेषता पहुंच; doStuffसाथ ही साथ फांसी की सजा का कोई कारण नहीं है । हालांकि अस्पष्टता के लिए अभी भी कुछ संभावनाएं हैं: यदि propertyएक सादे विशेषता के बजाय एक गणना की गई संपत्ति है, तो इसका कार्यान्वयन AttributeErrorआंतरिक रूप से बढ़ सकता है । यही कारण है कि इस तरह की लगभग सभी वास्तविक स्थितियों में, या getattrतो hasattrपकड़ना बेहतर होता है AttributeError
कार्ल मेयर

483

आप उपयोग कर सकते हैं hasattr()या पकड़ सकते हैं AttributeError, लेकिन यदि आप वास्तव में केवल डिफ़ॉल्ट के साथ विशेषता का मूल्य चाहते हैं यदि यह नहीं है, तो उपयोग करने के लिए सबसे अच्छा विकल्प है getattr():

getattr(a, 'property', 'default value')

14
यह पूर्वोक्त दोनों समस्याओं को हल करता है: ए) एक संभावित गुण के स्रोत की अस्पष्टता, बी) ईएएफपी दृष्टिकोण का संरक्षण।
पीटर एम। एलियास

6
यह कोड की लाइनों का 25% भी है। निश्चित रूप से इसका सबसे अच्छा समाधान होना चाहिए।
फतुहोकू

16
यह सबसे अच्छा समाधान है "यदि आप वास्तव में डिफ़ॉल्ट के साथ विशेषता का मूल्य चाहते हैं।" हालांकि मेरा मानना ​​है कि यह बहुत से लोग वास्तव में चाहते हैं जब वे कहते हैं कि वे यह पता लगाना चाहते हैं कि क्या कोई विशेषता मौजूद है, ओपी वास्तव में उत्तरार्द्ध के लिए पूछा, इसलिए यह उस प्रश्न के सीधे जवाब के लिए उचित है (हैट्टर, एट्रीब्यूटर) उच्च सूचीबद्ध करने के लिए ।
कार्ल मेयर

41

मुझे लगता है कि आप जिस चीज की तलाश कर रहे हैं वह है हेट्र । हालाँकि, मैं कुछ इस तरह की सलाह दूंगा यदि आप अजगर गुणों का पता लगाना चाहते हैं -

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

यहां नुकसान यह है कि गुण __get__कोड में विशेषता त्रुटियां भी पकड़ी जाती हैं।

नहीं तो करो-

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

डॉक्स: http://docs.python.org/library/functions.html
चेतावनी:
मेरी अनुशंसा का कारण यह है कि हैटट्रैट गुणों का पता नहीं लगाता है।
लिंक: http://mail.python.org/pipermail/python-dev/2005-Deuled/058498.html


तो, आपकी सलाह यह नहीं है कि आप इसे लागू करें!
साइलेंटगॉस्ट

ठीक है, बिल्कुल नहीं, अंतर्निहित IFF का उपयोग न करें जो आप गुणों का पता लगाना चाहते हैं। नहीं तो हेट्र पूरी तरह से अच्छा है।
बैटब्रेट

3
hasattrसामान्य रूप से ठीक गुणों का पता लगाता है। यह सिर्फ इतना है कि यह एक अपवाद को बढ़ाने का propertyकार्य करता है, जिसका अर्थ है कि ऐसी कोई विशेषता मौजूद नहीं है; लिंक किए गए पायथन मेलिंग सूची पोस्ट एक संपत्ति के बारे में है जो जब आप इसे एक्सेस करने का प्रयास करते हैं तो एक अपवाद उठाते हैं। सभी व्यावहारिक उद्देश्यों के लिए, विशेषता मौजूद नहीं है, क्योंकि यह कभी भी मूल्य नहीं पैदा करेगा। इसके अलावा, hasattrकेवल Py 3.1 और इससे पहले के सामान्य अपवादों को दबा देता है; 3.2+ में, यह केवल दबाता है ( Falseरिटर्न के साथ प्रतिस्थापित ) AttributeError
शैडो रेंजर

32

Pydoc के अनुसार, hasattr (obj, Prop) बस गेटअटर (obj, Prop) कहता है और अपवादों को पकड़ता है। इसलिए, यह एक कोशिश बयान के साथ विशेषता पहुंच को लपेटने और एट्रीब्यूट को पकड़ने के लिए बस के रूप में मान्य है क्योंकि यह पहले से ही हैट्रैट () का उपयोग करना है।

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

2
अच्छी तरह से वास्तव में अनुकूलित किया जा सकता है। जैसे पीपल के साथ।
ओडिन्हो - वेलमॉन्ट

6
+1। यह भी है सुरक्षित उपयोग करने की तुलना hasattrजब SomeClassओवरराइड __getattr__के बाद से hasattrपकड़ेगा सभी पायथन 2.x में अपवाद हैं, बस नहीं AttributeErrorहै जैसे आप उम्मीद करेंगे। यह पायथन 3.2 में तय किया गया था - कृपया एक साधारण वर्कअराउंड के लिए मेरा अन्य उत्तर देखें ।
मार्टिन गिस्लर

24

मैं इससे बचने का सुझाव देना चाहूंगा:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

उपयोगकर्ता @jpalecek ने इसका उल्लेख किया है: यदि AttributeErrorअंदर होता है doStuff(), तो आप खो गए हैं।

शायद यह दृष्टिकोण बेहतर है:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

सिर्फ यह भी हो सकता है: try: a.propertyबाएं हाथ की ओर कोई ज़रूरत नहीं है
पेट्रोज़ा

फिर आपको दूसरे ब्लॉक में a.property को दोहराना होगा, और यह विफल हो सकता है।
21ric अरुजो

13

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

एक स्थिति यह थी उपयोगी है यदि दो अलग-अलग वस्तुओं का एक ही नाम के साथ एक विशेषता है, लेकिन अलग अर्थ के साथ। केवल तभी उपयोग hasattrकरने से अजीब त्रुटियां हो सकती हैं।

एक अच्छा उदाहरण पुनरावृत्तियों और पुनरावृत्तियों के बीच का अंतर है ( इस प्रश्न को देखें )। __iter__पुनरावर्तक में तरीकों और एक iterable एक ही नाम है लेकिन शब्दार्थ काफी अलग हैं! तो hasattrबेकार है, लेकिन isinstanceएबीसी के साथ मिलकर एक स्वच्छ समाधान प्रदान करता है।

हालांकि, मैं मानता हूं कि ज्यादातर स्थितियों में hasattrदृष्टिकोण (अन्य उत्तरों में वर्णित) सबसे उपयुक्त समाधान है।


13

आशा करते हैं कि आप hasattr () की उम्मीद कर रहे हैं, लेकिन hasattr () से बचने की कोशिश करें और getattr () को प्राथमिकता दें। getattr () hasattr () से तेज़ है

hasattr () का उपयोग कर:

 if hasattr(a, 'property'):
     print a.property

अगर मैं कोई संपत्ति नहीं है, तो यहाँ मैं getattr का उपयोग संपत्ति प्राप्त करने के लिए कर रहा हूँ

   property = getattr(a,"property",None)
    if property:
        print property

11

EDIT : इस दृष्टिकोण की गंभीर सीमा है। यह काम करना चाहिए अगर वस्तु एक चलने योग्य है। कृपया नीचे टिप्पणी की जाँच करें।

यदि आप मेरी तरह Python 3.6 या उच्चतर का उपयोग कर रहे हैं , तो यह जांचने के लिए एक सुविधाजनक विकल्प है कि क्या किसी वस्तु में कोई विशेष विशेषता है:

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

हालाँकि, मुझे यकीन नहीं है कि अभी सबसे अच्छा तरीका कौन सा है। उपयोग करना hasattr(), उपयोग करना getattr()या उपयोग करना in। टिप्पणियों का स्वागत है।


6
inकीवर्ड चलने योग्य प्रकारों की जाँच के लिए काम करता है। उदाहरण के लिए, 'foo' in Noneत्रुटि फेंकता है TypeError: argument of type 'NoneType' is not iterable। यह तय करने के लिए कि क्या उपयोग करने से पहले टाइप करने योग्य है या नहीं in। गैर-चलने योग्य प्रकार जैसे किनारे के मामलों के लिए सही होने के बाद, आप संभवतः उपयोग करना बेहतर समझते हैं hasattr()क्योंकि यह किनारे के मामलों को संभालने के लिए डिज़ाइन किया गया है।
सेठ डेफ़र्टली

3
इसका विशेषता अभिगमन से कोई लेना-देना नहीं है। मुझे नहीं पता कि यह कैसे उठी। केवल इसी विशेषता का उपयोग करना है, यदि आप dictजावास्क्रिप्ट ऑब्जेक्ट्स के डिजाइन के समान "लाइटवेट ऑब्जेक्ट" के रूप में उपयोग कर रहे हैं , लेकिन अधिकांश सामान्य वर्ग सामान्य रूप से इसका समर्थन नहीं करेंगे (@SethDifley द्वारा उल्लिखित त्रुटि पर एक संस्करण प्राप्त करना) ।
शैडो रेंजर

2
अगर वर्ग में 'चर' .__ तानाशाही: ??
बेन


1

आप जाँच कर सकते हैं कि objectइसमें hasattrअंतर्निहित विधि का उपयोग करके विशेषता है या नहीं ।

उदाहरण के लिए यदि आपकी वस्तु है aऔर आप विशेषता के लिए जाँच करना चाहते हैंstuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

विधि हस्ताक्षर ही है hasattr(object, name) -> bool, तो है जो औसत objectहै विशेषता है, जिसमें दूसरा तर्क को पारित कर दिया है hasattrकी तुलना में यह बूलियन देता है Trueया Falseकी उपस्थिति के अनुसार nameवस्तु में विशेषता।


1

यह सुपर सरल है, बस dir(ऑब्जेक्ट का उपयोग करें )
यह ऑब्जेक्ट के प्रत्येक उपलब्ध फ़ंक्शन और विशेषता की सूची लौटाएगा।


1

एक और संभावित विकल्प, लेकिन यह निर्भर करता है कि आप पहले से क्या मतलब है :

undefined = object()

class Widget:

    def __init__(self):
        self.bar = 1

    def zoom(self):
        print("zoom!")

a = Widget()

bar = getattr(a, "bar", undefined)
if bar is not undefined:
    print("bar:%s" % (bar))

foo = getattr(a, "foo", undefined)
if foo is not undefined:
    print("foo:%s" % (foo))

zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
    zoom()

उत्पादन:

bar:1
zoom!

यह आपको किसी भी मूल्यवान विशेषताओं की जांच करने की अनुमति देता है।

परंतु! बहुत सावधानी बरतें कि आप अकस्मात नहीं रुकें और undefinedकई स्थानों की तुलना करें क्योंकिis उस स्थिति में यह कभी काम नहीं करेगा।

अपडेट करें:

उपरोक्त पैराग्राफ में जो मैं चेतावनी दे रहा था, उसके कारण कई अपरिभाषित जो कभी मेल नहीं खाते, मैंने हाल ही में इस पैटर्न को थोड़ा संशोधित किया है:

undefined = NotImplemented

NotImplemented, के साथ भ्रमित होने की नहीं NotImplementedError, एक अंतर्निहित है: यह एक जेएस के इरादे से अर्ध-मेल खाता है undefinedऔर आप हर जगह इसकी परिभाषा का पुन: उपयोग कर सकते हैं और यह हमेशा मेल खाएगा। कमियां यह है कि यह बूलियन में "सत्य" है और यह लॉग और स्टैक के निशान में अजीब लग सकता है (लेकिन आप जल्दी से इसे खत्म कर देते हैं जब आप जानते हैं कि यह केवल इस संदर्भ में प्रकट होता है)।


0

hasattr()सही उत्तर है। जो मैं जोड़ना चाहता हूं hasattr()वह यह है कि इसका उपयोग मुखरता के साथ भी किया जा सकता है (अनावश्यक ifबयानों से बचने के लिए और कोड को अधिक पठनीय बनाने के लिए):

assert hasattr(a, 'property'), 'object lacks property' 

एसओ पर एक अन्य उत्तर में कहा गया है : एसेर्ट्स का उपयोग उन परिस्थितियों का परीक्षण करने के लिए किया जाना चाहिए जो कभी नहीं होनी चाहिए। उद्देश्य एक भ्रष्ट कार्यक्रम राज्य के मामले में जल्दी दुर्घटना करना है।


यह सहायक है लेकिन हमेशा ऐसा नहीं हो सकता है। शायद मैं परीक्षण करना चाहता था कि क्या वस्तु में कोई संपत्ति है और फिर उसे पहली बार जोड़ते हैं, या शायद मुझे उस संपत्ति के लिए अलग कोड चलाना होगा। जब कोड जारी नहीं किया जा सकता है तो मुखर ठीक हो सकता है। लेकिन फिर, हमेशा ऐसा नहीं होता है। महत्वपूर्ण बात यह है hasattrकि आसपास के कोड का उपयोग नहीं है।
लुकास गेब्रियल सेंचेज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.