سؤال

هل هناك طريقة في بيثون لتحديد ما إذا كان كائن ما لديه بعض السمات؟ فمثلا:

>>> 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 قبل استخدامه؟

هل كانت مفيدة؟

المحلول

محاولة hasattr():

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

تحرير: انظر إجابة Zweiterlinde أدناه ، من يقدم نصيحة جيدة حول طلب المغفرة! نهج بيثوني جدا!

الممارسة العامة في بيثون هي أنه إذا كان من المحتمل أن تكون العقار هناك معظم الوقت ، فما عليك سوى تسميتها وإما السماح للاستثناء بالانتشار ، أو فخه بمحاولة/باستثناء الكتلة. من المحتمل أن يكون هذا أسرع من hasattr. إذا كان من المحتمل ألا تكون العقار هناك معظم الوقت ، أو لم تكن متأكدًا hasattr من المحتمل أن تكون أسرع من الوقوع مرارًا وتكرارًا في كتلة استثناء.

نصائح أخرى

كما جاريت هاردي أجاب ، hasattr سوف تفعل الحيلة. أود أن أضيف ، على الرغم من ذلك ، أن الكثيرين في مجتمع بيثون يوصون باستراتيجية "أسهل في طلب المغفرة من الإذن" (EAFP) بدلاً من "انظر قبل أن تقفز" (LBYL). انظر هذه المراجع:

EAFP vs Lbyl (كان إعادة: بخيبة أمل صغيرة حتى الآن)
EAFP مقابل lbylcode مثل pythonista: python الاصطلاحية

بمعنى آخر:

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

... يفضل:

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

يمكنك استخدام hasattr() أو اصطياد AttributeError, ، ولكن إذا كنت تريد حقًا قيمة السمة مع افتراضي إذا لم تكن موجودة ، فإن الخيار الأفضل هو فقط للاستخدام getattr():

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

أعتقد أن ما تبحث عنه هو Hasattr. ومع ذلك ، أوصي بشيء كهذا إذا كنت ترغب في اكتشاف خصائص بيثون-

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
تحذير:
سبب توصيتي هو أن Hasattr لا يكتشف الخصائص.
نهاية لهذه الغاية:http://mail.python.org/pipermail/python-dev/2005-december/058498.html

وفقًا لـ PYDOC ، يقوم Hasattr (OBJ ، Prop) ببساطة باستدعاء GetAttr (OBJ ، Prop) ويحصل على استثناءات. لذلك ، من الصحيح أن يلفت الوصول إلى السمة باستخدام عبارة TRAL و COST TRUSTIUNTERROR كما هو الحال في استخدام Hasattr () مسبقًا.

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

أود أن أقترح تجنب هذا:

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

ذكر ذلك jpalecek المستخدم: إذا كان AttributeError يحدث في الداخل doStuff(), ، أنت ضائع.

ربما يكون هذا النهج أفضل:

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

اعتمادًا على الموقف الذي يمكنك التحقق منه isinstance أي نوع من الكائن لديك ، ثم استخدم السمات المقابلة. مع إدخال فصول قاعدة مجردة في Python 2.6/3.0 ، أصبح هذا النهج أيضًا أكثر قوة (تسمح ABCs بشكل أساسي بطريقة أكثر تطوراً لكتابة البط).

كان أحد المواقف مفيدة إذا كان كائنين مختلفين لهما سمة تحمل نفس الاسم ، ولكن مع معنى مختلف. باستخدام فقط hasattr قد تؤدي بعد ذلك إلى أخطاء غريبة.

أحد الأمثلة اللطيفة هو التمييز بين المتكررين والتكرار (انظر هذه سؤال). ال __iter__ الأساليب في التكرار و ithable لها نفس الاسم ولكنها مختلفة تمامًا! لذا hasattr عديمة الفائدة ، لكن isinstance جنبا إلى جنب مع ABC يوفر حل نظيف.

ومع ذلك ، أوافق على أنه في معظم المواقف hasattr النهج (الموصوف في الإجابات الأخرى) هو الحل الأنسب.

آمل أن تتوقع hasattr () ، ولكن حاول تجنب hasattr () ويرجى تفضيل getAttr (). GetAttr () أسرع من Hasattr ()

باستخدام Hasattr ():

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

نفس الشيء هنا أستخدم getAttr للحصول على الممتلكات إذا لم يكن هناك خاصية ، فهو يعيد لا شيء

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

تعديل: هذا النهج له قيود خطيرة. يجب أن يعمل إذا كان الكائن متوقعة واحد. يرجى التحقق من التعليقات أدناه.

إذا كنت تستخدم بيثون 3.6 أو أعلى مثلي ، هناك بديل مناسب للتحقق مما إذا كان للكائن سمة معينة:

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

ومع ذلك ، لست متأكدًا من أفضل طريقة في الوقت الحالي. استخدام hasattr(), ، استخدام getattr() أو باستخدام in. التعليقات مرحب بها.

هذا نهج بديهي للغاية:

if 'property' in dir(a):
    a.property

يمكنك التحقق مما إذا كان 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 سمة في الكائن.

هذا بسيط للغاية ، فقط استخدم dir(هدف)
سيؤدي هذا إلى إرجاع قائمة كل وظيفة متوفرة وسمة للكائن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top