පයිතන් හි වස්තුවකට ලක්ෂණයක් තිබේදැයි දැන ගන්නේ කෙසේද


1661

වස්තුවකට කිසියම් ලක්ෂණයක් තිබේද යන්න තීරණය කිරීමට පයිතන්හි ක්‍රමයක් තිබේද? උදාහරණයක් වශයෙන්:

>>> 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?

Answers:


2383

උත්සාහ කරන්න hasattr():

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

සංස්කරණය කරන්න: සමාව ඉල්ලීම පිළිබඳව හොඳ උපදෙස් ලබා දෙන zweiterlinde ගේ පිළිතුර පහත බලන්න ! ඉතා පයිතොනික් ප්‍රවේශයක්!

පයිතන්හි ඇති සාමාන්‍ය සිරිත නම්, දේපල බොහෝ විට එහි තිබිය හැකි නම්, එය අමතා සරලවම එය අමතන්න. මෙය වඩා වේගවත් වනු ඇත hasattr. දේපල බොහෝ විට එහි නොතිබීමට ඉඩ තිබේ නම්, හෝ ඔබට විශ්වාස නැතිනම්, භාවිතා කිරීම hasattrනැවත නැවත ව්‍යතිරේක කොටසකට වැටීමට වඩා වේගවත් වනු ඇත.


19
නාම අවකාශයේ කාර්යයන් පරීක්ෂා කිරීම සඳහා ද ක්‍රියා කරන බව පෙනේ, උදා: import string hasattr(string, "lower")
riviera

15
hasattrහරියටම භාවිතා ම ය try/ except AttributeError: (Python 2.7 දී) hasattr වන docstring එය getattr අත උඩ පන්දු ව්යතිරේක භාවිතා කරන පවසයි.
ජෙෆ් ට්‍රැට්නර්

8
@JeffTratner: hasattrනෑ අවාසනාවකට වේ හරියටම ලෙස එම try: ... except AttributeError:සිට Python 2.x දී hasattrඇත සියලු හැර අල්ලා . කරුණාකර උදාහරණයක් සඳහා සහ සරල විසඳුමක් සඳහා මගේ පිළිතුර බලන්න .
මාටින් ගයිස්ලර්

645

ලෙස Jarret Hardie පිළිතුරු දෙමින්, hasattrඑම උපක්රමය කරනු ඇත. කෙසේ වෙතත්, පයිතන් ප්‍රජාවේ බොහෝ දෙනෙක් "ඔබ පැනීමට පෙර බලන්න" (LBYL) වෙනුවට "අවසරයට වඩා සමාව ඉල්ලීම පහසු" (EAFP) උපාය මාර්ගයක් නිර්දේශ කරන බව මම එකතු කිරීමට කැමැත්තෙමි. මෙම යොමු බලන්න:

EAFP එදිරිව LBYL (නැවත: මේ වන විට තරමක් කලකිරීමට පත් විය)
EAFP එදිරිව. LBYL ode කේතය මෙන් පයිතෝනිස්ටා: Idiomatic Python

එනම්:

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

... වඩාත් කැමති:

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

267
නමුත් ඩොස්ටෆ් () හි ඇති දෙයක් නොව, ගුණාංග දෝෂයට හේතු වූයේ a.property බව ඔබ පරීක්ෂා කරන්නේ කෙසේද? පෙනෙන විදිහට ඔබ එසේ නොකරන බව. සමාව ඉල්ලීම සැබවින්ම පහසු යැයි මම සිතමි, නමුත් බොහෝ විට එය ද වැරදිය.
jpalecek

293
EAFP පෙනේ ... උමතුයි. ඔබ විශේෂිත ලක්ෂණයක් සඳහා පරික්ෂා කරන අනාගත නඩත්තු ක්‍රමලේඛකයන්ට HasAttr විදුලි පණිවුඩ. ව්‍යතිරේකයක් ලබා ගැනීම අනාගත ක්‍රමලේඛකයින්ට කිසිවක් නොකියන අතර යමෙකු හාවා වළෙන් පහළට ගෙන යා හැකිය.
ඊතන් හෙල්මන්

75
5 e5: ඔබට මෙම නඩුවේ සාධාරණ කරුණක් ඇත, නමුත් බොහෝ අවස්ථාවලදී එකම නිවැරදි විකල්පය EAFP වේ. උදාහරණයක් ලෙස, ඔබ ගොනුවක පැවැත්ම පරීක්ෂා කර එය විවෘත කරන්නේ නම්, එය නියත වශයෙන්ම පවතිනු ඇතැයි අපේක්‍ෂා කරමින්, ඔබේ කේතය වැරදියි: ගොනුව මකා දැමිය හැකිය, නැතහොත් චෙක්පත සහ භාවිතය අතර නම් කළ හැකිය. මෙය TOCTOU දෝෂයක් ලෙස හැඳින්වේ (භාවිතයට ගත යුතු වේලාව පරීක්ෂා කිරීම) සහ බිඳවැටීම් ඇතිවීමට අමතරව ආරක්ෂක අවදානම් සහිත මූලාශ්‍රයක් ද විය හැකිය.
මැක්ස්

16
TEthanHeilman එය උමතුවක් වන්නේ ව්‍යතිරේකයේ ප්‍රභවයේ අපැහැදිලි බවක් ඇති විට පමණි, එය බොහෝ අවස්ථාවන්හිදී හොඳ සැලසුමකින් වළක්වා ගත හැකිය. උත්සාහය තුළ / හැරුණු විට / අවසාන වශයෙන් සාමාන්‍යයෙන් තාර්කික ව්‍යුහය සැකසීම මඟින් සෑම පරිභෝජන කේතයක් සඳහාම පූර්ව පරීක්‍ෂා කර බැලුවහොත් කේතය පැටවීමකට වඩා ශක්තිමත් (අඩු ක්‍රමලේඛ දෝෂ සහිත) තර්කනයක් ඇති කරයි. දෝෂ ඉතා පැහැදිලිව පෙනෙන අතර පරිභෝජන ක්‍රමලේඛකයන්ට ඒවා සමඟ deal ජුව ගනුදෙනු කිරීමේ අවස්ථාව ලබා දේ.
පීටර් එම්. එලියාස්

65
මෙහි බොහෝ අපැහැදිලි පැමිණිලි ලැබෙන්නේ නියැදි කේතය දුර්වල ලෙස ව්‍යුහගත වී ඇති බැවිනි. ඇතුළත ඇති එකම දෙය try:උත්සාහ කළ ගුණාංග ප්‍රවේශය විය යුතුය; ක්‍රියාත්මක කිරීම ද එතීමට හේතුවක් නැත doStuff. අවිනිශ්චිතතාවයට තවමත් යම් විභවයක් ඇත: propertyසරල ගුණාංගයක් වෙනුවට ගණනය කළ දේපලක් නම් , එය ක්‍රියාත්මක කිරීම AttributeErrorඅභ්‍යන්තරව ඉහළ නැංවිය හැකිය . මේ නිසා සෑම සැබෑ තත්වයකදීම පාහේ අල්ලා getattrගැනීමට hasattrහෝ අල්ලා ගැනීමට වඩා සුදුසු වන්නේ මේ නිසා ය AttributeError.
කාල් මේයර්

493

ඔබට භාවිතා කිරීමට hasattr()හෝ අල්ලා ගැනීමට හැකිය AttributeError, නමුත් ඔබට එය අවශ්‍ය නම් පෙරනිමියෙන් ගුණාංගයේ වටිනාකම අවශ්‍ය නම් එය භාවිතා කිරීම හොඳම විකල්පයයි getattr():

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

14
මෙය ඉහත සඳහන් ගැටළු දෙකම විසඳයි: අ) විය හැකි ආරෝපණ දෝෂයක ප්‍රභවයේ නොපැහැදිලි බව, ආ) ඊඒඑෆ්පී ප්‍රවේශය ආරක්ෂා කිරීම.
පීටර් එම්. එලියාස්

6
එය කේත රේඛාවලින් 25% කි. නිසැකවම මෙය හොඳම විසඳුම විය යුතුය.
fatuhoku

16
මෙය හොඳම විසඳුමයි "ඔබට පෙරනිමියෙන් ගුණාංගයේ වටිනාකම අවශ්‍ය නම්." බොහෝ අය ඇත්ත වශයෙන්ම අවශ්‍ය වන්නේ ගුණාංගයක් තිබේදැයි සොයා ගැනීමට අවශ්‍ය යැයි මා විශ්වාස කළත්, OP ඇත්ත වශයෙන්ම දෙවැන්න ඉල්ලා සිටියේය, එබැවින් එම ප්‍රශ්නයට සෘජු පිළිතුරු (hasattr, AttributeError) ඉහළින් ලැයිස්තුගත කිරීම සාධාරණ ය. .
කාල් මේයර්

43

මම හිතන්නේ ඔබ සොයන දේ හසත්ර් ය . කෙසේ වෙතත්, ඔබට පයිතන් ගුණාංග හඳුනා ගැනීමට අවශ්‍ය නම් මම මේ වගේ දෙයක් නිර්දේශ කරමි -

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-December/058498.html


3
hasattrසාමාන්‍යයෙන් ගුණාංග හඳුනා ගනී. එය propertyඑතී ඇති ශ්‍රිතයේ ව්‍යතිරේකයක් මතු කිරීමට සලකන්නේ එවැනි ලක්ෂණයක් නොපවතින බැවිනි. සම්බන්ධිත පයිතන් තැපැල් ලැයිස්තුව යනු ඔබ එයට ප්‍රවේශ වීමට උත්සාහ කරන විට ව්‍යතිරේකයක් මතු කරන දේපලකි. සියලු ප්‍රායෝගික අරමුණු සඳහා, කියූ ගුණාංගය නොපවතී, මන්ද එය කිසි විටෙකත් වටිනාකමක් නොලැබේ. එසේම, hasattrපයි 3.1 සහ ඊට පෙර පොදුවේ ව්‍යතිරේකයන් පමණක් මර්දනය කරයි; 3.2+ දී, එය යටපත් කරයි ( Falseආපසු පැමිණීම වෙනුවට ) AttributeError.
ෂැඩෝ රේන්ජර්

33

Pydoc ට අනුව, hasattr (obj, prop) හුදෙක් getattr (obj, prop) ලෙස හඳුන්වන අතර ව්‍යතිරේකයන් අල්ලා ගනී. එබැවින්, උත්සාහක ප්‍රකාශයක් සමඟ ආරෝපණ ප්‍රවේශය එතීම හා පෙර හැට්ටර් () භාවිතා කිරීම මෙන්ම ගුණාංග දෝෂය අල්ලා ගැනීම වලංගු වේ.

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

2
හොඳයි hasattr ඇත්ත වශයෙන්ම ප්‍රශස්තිකරණය කළ හැකිය . උදා: පයිප්ප සමඟ.
ඔඩින්හෝ - වෙල්මොන්ට්

6
+1. ඔබ බලාපොරොත්තු වූවා සේම , පයිතන් 2.x හි ඇති සියලුම ව්‍යතිරේකයන් අල්ලා ගන්නා බැවින්, අතිච්ඡාදනය වන විට භාවිතා කිරීමට වඩා මෙය ආරක්ෂිත වේ . මෙය පයිතන් 3.2 හි සවි කර ඇත - කරුණාකර සරල විසඳුමක් සඳහා මගේ අනෙක් පිළිතුර බලන්න . hasattrSomeClass__getattr__hasattrAttributeError
මාටින් ගයිස්ලර්

25

මෙය වළක්වා ගැනීමට මම යෝජනා කිරීමට කැමැත්තෙමි:

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

Pjpalecek පරිශීලකයා එය සඳහන් කළේ: AttributeErrorඇතුළත යම් දෙයක් සිදුවුවහොත් doStuff(), ඔබ නැති වී යයි.

සමහර විට මෙම ප්‍රවේශය වඩා හොඳය:

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

14

ඔබ hasattr () බලාපොරොත්තු වේ යැයි සිතමු, නමුත් hasattr () වළක්වා ගැනීමට උත්සාහ කරන්න, කරුණාකර getattr () ට වැඩි කැමැත්තක් දක්වන්න. getattr () hasattr () ට වඩා වේගවත්ය

hasattr () භාවිතා කිරීම:

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

මෙහි දී මම දේපල ලබා ගැනීමට getattr භාවිතා කරමි

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

13

තත්වය මත පදනම්ව ඔබට ඇත්තේ isinstanceකුමන ආකාරයේ වස්තුවක්ද යන්න පරීක්ෂා කර බලා ඊට අනුරූප ගුණාංග භාවිතා කරන්න. පයිතන් 2.6 / 3.0 හි වියුක්ත පාදක පන්ති හඳුන්වාදීමත් සමඟ මෙම ප්‍රවේශය වඩාත් බලවත් වී ඇත (මූලික වශයෙන් ABCs තාරාවන්ගේ යතුරු ලියනය කිරීමේ වඩාත් නවීන ක්‍රමයක් සඳහා ඉඩ ලබා දේ).

එක් තත්වයක් නම් මෙය ප්‍රයෝජනවත් වනුයේ විවිධ වස්තූන් දෙකකට එකම නමක් සහිත නමුත් විවිධ අර්ථයන් සහිත ලක්ෂණයක් තිබේ නම්. පමණක් භාවිතා කිරීමෙන් hasattrඅමුතු දෝෂ ඇති විය හැකිය.

එක් හොඳ උදාහරණයක් වන්නේ iterator සහ iterables අතර වෙනසයි ( මෙම ප්‍රශ්නය බලන්න ). මෙම __iter__සහ iterator දී ක්රම යනු iterable එකම නම තිබේ නමුත් ශබ්දාර්ථයෙන් වඩා බෙහෙවින් වෙනස් වේ! ඒ නිසා hasattrද නිෂ්ඵල, නමුත් isinstanceඒබීසී හි සමග එක්ව පිරිසිදු විසඳුමක් ලබා දෙයි.

කෙසේ වෙතත්, බොහෝ අවස්ථාවන්හිදී hasattrප්‍රවේශය (වෙනත් පිළිතුරු වල විස්තර කර ඇති) වඩාත්ම සුදුසු විසඳුම බව මම එකඟ වෙමි .


13

සංස්කරණය කරන්න : මෙම ප්‍රවේශයට බරපතල සීමාවන් ඇත. වස්තුව නැවත ලබා ගත හැකි එකක් නම් එය ක්‍රියාත්මක විය යුතුය . කරුණාකර පහත අදහස් පරීක්ෂා කරන්න.

ඔබ මා වැනි පයිතන් 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ජාවාස්ක්‍රිප්ට් වස්තූන්ගේ සැලසුමට සමාන “සැහැල්ලු වස්තුවක්” ලෙස භාවිතා කරන්නේ නම්, නමුත් බොහෝ සාමාන්‍ය පංති පොදුවේ මෙයට සහාය නොදක්වයි (ethSethDifley සඳහන් කළ දෝෂය මත ප්‍රභේදයක් ලබා ගැනීම) .
ෂැඩෝ රේන්ජර්


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, එය ගොඩනංවන ලද්දකි: එය JS හි අභිප්‍රාය අර්ධ වශයෙන් ගැලපෙන අතර undefinedඔබට එහි අර්ථ දැක්වීම සෑම තැනකම නැවත භාවිතා කළ හැකි අතර එය සැමවිටම ගැලපේ. මෙහි ඇති අඩුපාඩු වන්නේ එය බූලියන් වල "සත්‍ය" වන අතර එය ල logs ු-සටහන් හා සිරස් හෝඩුවාවන්හි අමුතු පෙනුමක් ලබා දිය හැකිය (නමුත් මෙම සන්දර්භය තුළ පමණක් එය දිස්වන බව ඔබ දැනගත් විට ඔබ එය ඉක්මණින් ජය ගනී).


0

බිල්ඩින් ක්‍රමය 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වස්තුව දී විශේෂණය.


0

hasattr()නිවැරදි පිළිතුරයි. මට එකතු කිරීමට අවශ්‍ය වන්නේ එය තහවුරු කිරීමhasattr() සමඟ හොඳින් භාවිතා කළ හැකි වීමයි (අනවශ්‍ය ප්‍රකාශ වළක්වා ගැනීමට සහ කේතය වඩාත් කියවිය හැකි කිරීමට):if

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

SO පිළිබඳ තවත් පිළිතුරක සඳහන් කර ඇති පරිදි : කිසි විටෙකත් සිදු නොවිය යුතු තත්වයන් පරීක්ෂා කිරීම සඳහා ප්‍රකාශ භාවිතා කළ යුතුය. දූෂිත වැඩසටහන් රාජ්‍යයක මුල් අවදියේදීම බිඳ වැටීම මෙහි අරමුණයි.


මෙය ප්‍රයෝජනවත් නමුත් සෑම විටම එසේ නොවිය හැකිය. සමහර විට මට අවශ්‍ය වූයේ වස්තුවට දේපලක් ඇත්දැයි පරීක්ෂා කර පළමු වරට එය එකතු කිරීම හෝ එම දේපල ඇති වස්තු සඳහා විවිධ කේත ධාවනය කිරීමට මට සිදු විය හැකිය. කේතයට ඉදිරියට යාමට නොහැකි වූ විට ප්‍රකාශය හොඳින් විය හැකිය. නමුත් නැවතත්, සෑම විටම එසේ නොවේ. වැදගත් දෙය වන්නේ hasattrඅවට කේතය භාවිතා නොකිරීමයි.
ලූකස් ගේබ්‍රියෙල් සාන්චෙස්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.