كيف تعرف ما إذا كان للكائن سمة في بيثون
-
03-07-2019 - |
سؤال
هل هناك طريقة في بيثون لتحديد ما إذا كان كائن ما لديه بعض السمات؟ فمثلا:
>>> 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(
هدف)
سيؤدي هذا إلى إرجاع قائمة كل وظيفة متوفرة وسمة للكائن.