වස්තුවක වර්ගය තීරණය කරන්න?


1794

විචල්යයක් යනු ලැයිස්තුවක්, ශබ්ද කෝෂයක් හෝ වෙනත් දෙයක්ද යන්න තීරණය කිරීමට සරල ක්රමයක් තිබේද? මා විසින් වස්තුවක් නැවත ලබා ගන්නේ එය එක්තරා ආකාරයක විය හැකි අතර වෙනස පැවසීමට මට හැකියාව තිබිය යුතුය.


44
පොදුවේ මම ඔබ සමඟ එකඟ වන අතර, එය දැන ගැනීමට උපකාරී වන අවස්ථා තිබේ. මෙම විශේෂ අවස්ථාවෙහිදී මම ඉක්මන් අනවසරයෙන් ඇතුළුවීම සිදු කළෙමි. නමුත් සමහර අවස්ථාවලදී - පරාවර්තනය භාවිතා කරන විට, උදාහරණයක් ලෙස - ඔබ කටයුතු කරන්නේ කුමන ආකාරයේ වස්තුවක් දැයි දැන ගැනීම වැදගත්ය.
ජස්ටින් එතියර්

67
@ එස්. ලොට් මම එයට එකඟ නොවෙමි; වර්ගය දැන ගැනීමට හැකි වීමෙන්, ඔබට ලස්සන ප්‍රභේද ආදානය සමඟ ගනුදෙනු කළ හැකි අතර තවමත් නිවැරදි දේ කරන්න. පිරිසිදු තාරා-ටයිප් කිරීම (උදා: ගසක .බාර්ක් () ක්‍රමය යනු බල්ලෙකුට වඩා සම්පූර්ණයෙන්ම වෙනස් දෙයකි.) නිදසුනක් ලෙස, ඔබට යම් කාර්යයක් කළ හැකි ශ්‍රිතයක් කළ හැකිය. නූලක් පිළිගන්නා ගොනුවක් (උදා: මාර්ගයක්), මාර්ග වස්තුවක් හෝ ලැයිස්තුවක්. සියල්ලටම විවිධ අතුරුමුහුණත් ඇත, නමුත් අවසාන ප්‍රති result ලය සමාන වේ: එම ගොනුවේ යම් ක්‍රියාමාර්ගයක් ගන්න.
රොබට් පී

22
L එස්. ලොට් මම හිතුවා එය ව්‍යාජ උදාහරණයක් බව පැහැදිලියි; එසේ වුවද එය තාරාවන් යතුරු ලියනය කිරීමේ ප්‍රධාන අසාර්ථක ලක්ෂ්‍යයක් වන අතර tryඑය උදව් නොකරන එකකි . නිදසුනක් ලෙස, පරිශීලකයෙකුට නූලකින් හෝ අරාවකින් සමත් විය හැකි බව ඔබ දැන සිටියේ නම්, දෙකම සුචිගත කළ හැකි නමුත් එම දර්ශකය යනු සම්පූර්ණයෙන්ම වෙනස් දෙයක්. එවැනි අවස්ථාවන්හිදී උත්සාහක දිනුමක් මත රඳා සිටීම අනපේක්ෂිත හා අමුතු ආකාරයකින් අසාර්ථක වනු ඇත. එක් විසඳුමක් වන්නේ වෙනම ක්‍රමයක් සෑදීමයි, තවත් ක්‍රමයක් කුඩා වර්ගයේ පරීක්ෂාවක් එක් කිරීම. එකම දේ කරන බහු ක්‍රම වලට වඩා මම පෞද්ගලිකව බහුමාමක හැසිරීමට කැමැත්තෙමි ... නමුත් එය මා පමණි :)
රොබට් පී

22
@ එස්. ලොට්, ඒකක පරීක්ෂණ ගැන කුමක් කිව හැකිද? සමහර විට ඔබට අවශ්‍ය වන්නේ ශ්‍රිතයක් නිවැරදි වර්ගයට අයත් දෙයක් බව තහවුරු කර ගැනීමයි. ඇත්ත උදාහරණයක් නම් ඔබට පන්ති කර්මාන්ත ශාලාවක් ඇති විට.
එලියට් කැමරන්

17
අඩු උපක්‍රමශීලී උදාහරණයක් සඳහා, අනුක්‍රමික / ඩෙසරයිලයිසර් සලකා බලන්න. අර්ථ දැක්වීම අනුව ඔබ පරිශීලක සපයන වස්තු සහ අනුක්‍රමික නිරූපණයක් අතර පරිවර්තනය වේ. අනුක්‍රමිකයාට ඔබ ඇතුල් වූ වස්තුව වර්ගය තීරණය කිරීමට අවශ්‍ය වන අතර, ධාවන වේලාව විමසීමෙන් තොරව ඩෙසරීකරණය කළ වර්ගය තීරණය කිරීමට ඔබට ප්‍රමාණවත් තොරතුරු නොමැති විය හැකිය (හෝ අවම වශයෙන්, එය ඇතුල් වීමට පෙර නරක දත්ත අල්ලා ගැනීම සඳහා සනීපාරක්ෂාව පරීක්ෂා කිරීම සඳහා ඔබට එය අවශ්‍ය විය හැකිය. ඔබේ පද්ධතිය!)
කාල්

Answers:


1988

වස්තුවක වර්ගය හඳුනා ගැනීමට ඔබට උපකාරී වන සාදන ලද කාර්යයන් දෙකක් තිබේ. ඔබට භාවිතා කල හැකි type() ඔබ වස්තුව පිළිබඳ නිශ්චිත වර්ගය අවශ්ය නම්, සහ isinstance()කිරීමට පරීක්ෂා දෙයක් එරෙහිව වස්තුව ගණය. සාමාන්‍යයෙන්, ඔබට isistance()බොහෝ විට භාවිතා කිරීමට අවශ්‍ය වන්නේ එය ඉතා ශක්තිමත් බැවින් වර්ග උරුමයට සහාය වන බැවිනි.


වස්තුවක සත්‍ය වර්ගය ලබා ගැනීම සඳහා, ඔබ ගොඩනංවන ලද type()ශ්‍රිතය භාවිතා කරයි. එකම පරාමිතිය ලෙස වස්තුවක් පසු කිරීමෙන් එම වස්තුවේ වර්ගය නැවත ලැබෙනු ඇත:

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True

මෙය ඇත්ත වශයෙන්ම අභිරුචි වර්ග සඳහාද ක්‍රියා කරයි:

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

type()එය වස්තුවේ ආසන්නතම වර්ගය පමණක් ආපසු ලබා දෙන බව සලකන්න , නමුත් ටයිප් උරුමය ගැන ඔබට පැවසිය නොහැක.

>>> type(b) is Test1
False

එය ආවරණය කිරීම සඳහා, ඔබ isinstanceශ්‍රිතය භාවිතා කළ යුතුය . මෙය ඇත්ත වශයෙන්ම සාදන ලද වර්ග සඳහා ද ක්‍රියා කරයි:

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance()සාමාන්‍යයෙන් වස්තුවක වර්ගය සහතික කිරීම සඳහා වඩාත් සුදුසු ක්‍රමය වන්නේ එය ව්‍යුත්පන්න වර්ග ද පිළිගන්නා බැවිනි. එබැවින් ඔබට ඇත්ත වශයෙන්ම වර්ගයේ වස්තුව අවශ්‍ය නොවන්නේ නම් (කුමන හේතුවක් නිසා හෝ) භාවිතා isinstance()කිරීම වඩාත් සුදුසුය type().

දෙවන පරාමිතිය isinstance()ද වර්ග රාශියක් පිළිගනී, එබැවින් එකවර බහුවිධ වර්ග පරීක්ෂා කළ හැකිය. isinstanceවස්තුව එම වර්ග වලින් එකක් නම් එය සත්‍ය වේ.

>>> isinstance([], (tuple, list, set))
True

68
මා සිතන්නේ වර්ගයන් තනි is==
බොත්තම්

18
@gnibbler, සමහර අවස්ථාවලදී ඔබ යතුරු ලියනය කිරීම (ආරම්භ කිරීම සඳහා ඔබ විසින් නොකළ යුතු), isinstanceකෙසේ ==හෝ කැමති ආකෘතිය වේ, එබැවින් isභාවිතා කිරීම හෝ භාවිතා කිරීම අවශ්‍ය නොවේ.
මයික් ග්‍රැහැම්

23
Ike මයික් ග්‍රැහැම්, typeහොඳම පිළිතුර ලැබෙන අවස්ථා තිබේ. වන අවස්ථා තිබෙනවා isinstanceහොඳම පිළිතුර වන්නේ හා තාරා ටයිප් හොඳම පිළිතුර විට උද්ගත වනු ඇත. සියලු විකල්පයන් දැන ගැනීම වැදගත් වන අතර එමඟින් තත්වයට වඩාත් සුදුසු දේ තෝරා ගත හැකිය.
ජෝන් ලා රූයි

6
@gnibbler, එය එසේ විය හැකිය, මම තවම type(foo) is SomeTypeවඩා හොඳ තත්වයට නොපැමිණි නමුත් isinstance(foo, SomeType).
මයික් ග්‍රැහැම්

5
okepoke: මම PEP8 ගැන සම්පුර්ණයෙන්ම එකඟ වෙමි, නමුත් ඔබ මෙහි පිදුරුකරුවෙකුට පහර දෙති: ස්වේන්ගේ තර්කයේ වැදගත් කොටස PEP8 නොවේ, නමුත් ඔබට isinstanceඔබේ භාවිත කට්ටලය සඳහා භාවිතා කළ හැකිය (වර්ග ගණනාවක් පරීක්ෂා කිරීම), සහ සමඟ ඔබට උප පංති අල්ලා ගත හැකි විශාල වාසියක් ඇති වාක්‍ය ඛණ්ඩයක් පිරිසිදු කරන්න. භාවිතා OrderedDictකරන අයෙක් ඔබේ කේතය අසාර්ථක වීමට වෛර කරයි, මන්ද එය පිරිසිදු නියෝග පිළිගන්නා බැවිනි.
පියාඹන බැටළුවන්

167

ඔබට එය භාවිතා කළ හැකිය type():

>>> a = []
>>> type(a)
<type 'list'>
>>> f = ()
>>> type(f)
<type 'tuple'>

40

try... exceptබ්ලොක් එකක් භාවිතා කිරීම වඩා පයිතොනික් විය හැකිය . ඒ ආකාරයෙන්, ඔබට ලැයිස්තුවක් වැනි පන්තියක් තිබේ නම්, හෝ නියෝගයක් වැනි ක්වාක් තිබේ නම්, එහි වර්ගය සැබවින්ම කුමක් වුවත් එය නිසි ලෙස හැසිරෙනු ඇත .

පැහැදිලි කිරීම සඳහා, විචල්‍ය වර්ග අතර “වෙනස පැවසීමේ” ක්‍රමය තාරා ටයිප් කිරීම ලෙස හැඳින්වේ : විචල්‍යයක් ප්‍රතිචාර දක්වන ක්‍රම (සහ ආපසු එන වර්ග) ඔබේ සබ්මැරීනය අපේක්ෂා කරන තාක් කල්, ඔබ බලාපොරොත්තු වන ආකාරයට සලකන්න වීමට. නිදසුනක් ලෙස, ඔබ වරහන ක්‍රියාකරුවන් සමඟ අධික ලෙස පටවන getattrහා setattrවිනෝදජනක අභ්‍යන්තර යෝජනා ක්‍රමයක් භාවිතා කරන පන්තියක් තිබේ නම් , එය අනුකරණය කිරීමට උත්සාහ කරන්නේ නම් එය ශබ්ද කෝෂයක් ලෙස හැසිරීම සුදුසුය.

type(A) is type(B)පරික්ෂා කිරීමේ අනෙක් ගැටළුව නම් A, උප පංතියක් නම් B, එය ඇගයීමට ලක් කරන්නේ falseකවදාද, ක්‍රමලේඛිකව, ඔබ එය බලාපොරොත්තු වනු ඇත true. වස්තුවක් ලැයිස්තුවක උප පංතියක් නම්, එය ලැයිස්තුවක් මෙන් ක්‍රියා කළ යුතුය: අනෙක් පිළිතුරෙහි දක්වා ඇති පරිදි වර්ගය පරීක්ෂා කිරීමෙන් මෙය වළක්වනු ඇත. (isinstance කෙසේ වෙතත් ක්‍රියා කරනු ඇත).


16
තාරා ටයිප් කිරීම ඇත්ත වශයෙන්ම වෙනස පැවසීම නොවේ. එය පොදු අතුරු මුහුණතක් භාවිතා කිරීම ගැන ය.
ජස්ටින් එතියර්

5
ප්‍රවේශම් වන්න - බොහෝ කේතකරණ ශෛලියේ මාර්ගෝපදේශකයින් නිර්දේශ කරන්නේ කේතයේ සාමාන්‍ය පාලන ප්‍රවාහයේ කොටසක් ලෙස ව්‍යතිරේක හැසිරවීම භාවිතා නොකිරීමටයි. try... exceptඔබට දෝෂ සමඟ කටයුතු කිරීමට අවශ්‍ය විට හොඳ විසඳුමකි, නමුත් වර්ගය මත පදනම්ව හැසිරීම තීරණය කිරීමේදී නොවේ.
රෙන්ස් වැන් ඩර් හයිජ්ඩන්

34

වස්තුවක අවස්ථා වලදී ඔබට:

__class__

ගුණාංගය. මෙන්න පයිතන් 3.3 කොන්සෝලයෙන් ලබාගත් නියැදියකි

>>> str = "str"
>>> str.__class__
<class 'str'>
>>> i = 2
>>> i.__class__
<class 'int'>
>>> class Test():
...     pass
...
>>> a = Test()
>>> a.__class__
<class '__main__.Test'>

පයිතන් 3.x සහ නිව්-ස්ටයිල් පංතිවල (විකල්පයක් ලෙස පයිතන් 2.6 වෙතින් ලබා ගත හැකිය) පන්තිය සහ වර්ගය ඒකාබද්ධ කර ඇති අතර මෙය කිසියම් අවස්ථාවක අනපේක්ෂිත ප්‍රති .ලවලට හේතු විය හැකි බවට පරිස්සම් වන්න. ප්රධාන වශයෙන් මෙම හේතුව නිසා මා කැමති වර්ග / පන්ති පරීක්ෂා කිරීමේ ක්රමය වන්නේ ක්රියාකාරිත්වය තුළ ගොඩනගා ඇති සමස්ථයයි .


2
අවසානයේ ඔබේ කරුණ ඉතා වැදගත් ය. type (obj) යනු පන්තිය නිවැරදිව ක්‍රියා නොකරයි, නමුත් isinstance උපක්‍රමය කළේය. කෙසේ හෝ සමතුලිතතාවයට වැඩි කැමැත්තක් දක්වන බව මට වැටහී ඇත, නමුත් පිළිගත් පිළිතුරෙහි යෝජනා කර ඇති පරිදි ව්‍යුත්පන්න වර්ග පරීක්ෂා කිරීමට වඩා එය ප්‍රයෝජනවත් වේ.
mstbaum

__class__පයිතන් 2.x හි බොහෝ දුරට හරි, පයිතන් හි ඇති එකම වස්තුව වන්නේ __class__ගුණාංග නොමැති පැරණි පන්ති AFAIK ය. ඔබේ පයිතන් 3 සැලකිලිමත් වීම මට තේරෙන්නේ නැත - එවැනි අනුවාදයක, සෑම වස්තුවකටම __class__නිසි පන්තියට යොමු වන ලක්ෂණයක් ඇත.
ඇලන් ෆ්‍රැන්සෝනි

21

පයිතන් වස්තුවක වර්ගය තීරණය කරන්න

සමඟ වස්තුවක වර්ගය තීරණය කරන්න type

>>> obj = object()
>>> type(obj)
<class 'object'>

එය ක්‍රියාත්මක වුවද, ද්විත්ව අවධාරනය කරන ගුණාංග වළක්වා ගන්න __class__- ඒවා අර්ථාන්විතව පොදු නොවන අතර, සමහර විට මෙම අවස්ථාවේ දී එසේ නොවුවද, බිල්ඩින් ක්‍රියාකාරිත්වයන්ට වඩා හොඳ හැසිරීමක් ඇත.

>>> obj.__class__ # avoid this!
<class 'object'>

පරීක්ෂා කිරීම ටයිප් කරන්න

විචල්යයක් යනු ලැයිස්තුවක්, ශබ්ද කෝෂයක් හෝ වෙනත් දෙයක්ද යන්න තීරණය කිරීමට සරල ක්රමයක් තිබේද? මා විසින් වස්තුවක් නැවත ලබා ගන්නේ එය එක්තරා ආකාරයක විය හැකි අතර වෙනස පැවසීමට මට හැකියාව තිබිය යුතුය.

හොඳයි, එය වෙනස් ප්‍රශ්නයකි, වර්ගය භාවිතා නොකරන්න - භාවිතා කරන්න isinstance:

def foo(obj):
    """given a string with items separated by spaces, 
    or a list or tuple, 
    do something sensible
    """
    if isinstance(obj, str):
        obj = str.split()
    return _foo_handles_only_lists_or_tuples(obj)

උප කාණ්ඩය මඟින් ඔබේ පරිශීලකයා දක්ෂ හෝ සංවේදී යමක් කළ හැකි අවස්ථාව මෙය ආවරණය කරයි str- ලිස්කොව් ආදේශනයේ මූලධර්මයට අනුව, ඔබේ කේතය කඩ නොකර උප පංති අවස්ථා භාවිතා කිරීමට ඔබට අවශ්‍යය - සහ isinstanceමේ සඳහා සහාය වේ.

සාරාංශ භාවිතා කරන්න

ඊටත් වඩා හොඳයි, ඔබට නිශ්චිත වියුක්ත මූලික පන්තියක් collectionsහෝ සිට numbers:

from collections import Iterable
from numbers import Number

def bar(obj):
    """does something sensible with an iterable of numbers, 
    or just one number
    """
    if isinstance(obj, Number): # make it a 1-tuple
        obj = (obj,)
    if not isinstance(obj, Iterable):
        raise TypeError('obj must be either a number or iterable of numbers')
    return _bar_sensible_with_iterable(obj)

නැතහොත් පැහැදිලිව ටයිප් කරන්න

නැතහොත්, සියල්ලටම වඩා, තාරා-ටයිප් කිරීම භාවිතා කරන්න, ඔබේ කේතය පැහැදිලිව ටයිප් නොකරන්න. තාරා-ටයිප් කිරීම වඩාත් අලංකාරවත් හා අඩු වාචිකතාවයකින් ලිස්කොව් ආදේශනයට සහාය වේ.

def baz(obj):
    """given an obj, a dict (or anything with an .items method) 
    do something sensible with each key-value pair
    """
    for key, value in obj.items():
        _baz_something_sensible(key, value)

නිගමනය

  • typeඇත්ත වශයෙන්ම නිදර්ශන පන්තියක් ලබා ගැනීමට භාවිතා කරන්න .
  • isinstanceසත්‍ය උප පංති හෝ ලියාපදිංචි වියුක්තයන් සඳහා පැහැදිලිව පරීක්ෂා කිරීමට භාවිතා කරන්න .
  • තේරුමක් ඇති තැන ටයිප් කිරීම වළක්වා ගන්න.

පැහැදිලිව පරීක්ෂා කිරීම වෙනුවට සෑම විටම try/ exceptවෙනුවට තිබේ.
toonarmycaptain

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

13

ඔබට භාවිතා කළ හැකිය type()හෝ isinstance().

>>> type([]) is list
True

listඑකම නමේ වත්මන් විෂය පථයට විචල්‍යයක් පැවරීමෙන් ඔබට ක්ලෝබර් හෝ වෙනත් වර්ගයක් කළ හැකි බවට අනතුරු අඟවන්න .

>>> the_d = {}
>>> t = lambda x: "aight" if type(x) is dict else "NOPE"
>>> t(the_d) 'aight'
>>> dict = "dude."
>>> t(the_d) 'NOPE'

ඉහත දැක්වෙන්නේ dictඑය නූලකට නැවත පැවරීමයි, එබැවින් පරීක්ෂණය:

type({}) is dict

... අසමත්.

මෙය වටහා ගැනීමට සහ type()වඩාත් ප්‍රවේශමෙන් භාවිතා කිරීමට :

>>> import __builtin__
>>> the_d = {}
>>> type({}) is dict
True
>>> dict =""
>>> type({}) is dict
False
>>> type({}) is __builtin__.dict
True

2
බිල්ඩින් දත්ත වර්ගයක නම සෙවනැල්ල කිරීම මෙම නඩුවට නරක බව පෙන්වා දීම අවශ්‍ය යැයි මට විශ්වාස නැත. dictවැනි වෙනත් බොහෝ කේත සඳහා ඔබේ නූල අසමත් වනු ඇත dict([("key1", "value1"), ("key2", "value2")]). එවැනි ගැටළු වලට පිළිතුර "එසේ නොකරන්න" යන්නයි . බිල්ඩින් වර්ගයේ නම් සෙවනැලි නොකර දේවල් නිසි ලෙස ක්‍රියාත්මක වනු ඇතැයි අපේක්ෂා කරන්න.
Blckknght

3
"එසේ නොකරන්න" කොටස සම්බන්ධයෙන් මම ඔබ සමඟ එකඟ වෙමි. නමුත් ඇත්ත වශයෙන්ම යමෙකුට යමක් නොකරන ලෙස පැවසීම ඔබ අවම වශයෙන් එසේ නොකළ යුත්තේ මන්දැයි පැහැදිලි කළ යුතු අතර මම සිතුවේ මෙය කිරීමට සුදුසු අවස්ථාවක් බවයි. මා අදහස් කළේ අවලස්සන පෙනුම සහ ඔවුන් එය කිරීමට අකමැති වීමට හේතුව නිදර්ශනය කිරීම, ඔවුන් තීරණය කිරීමට ඉඩ හැරීමයි.
deed02392

සම්භාව්‍ය අවස්ථා සඳහා පයිතන් 2.x හි අපේක්ෂිත පරිදි වර්ගය () ක්‍රියා නොකරයි.
ඇලන් ෆ්‍රැන්සෝනි

5

ප්‍රශ්න සෑහෙන්න පරණ වුවත්, නිසි ක්‍රමයක් සොයා ගැනීමේදී මම මේ ගැන පැකිලී ගිය අතර, අවම වශයෙන් පයිතන් 2.x සඳහා (පයිතන් 3 පරීක්ෂා නොකළ නමුත් එය සම්භාව්‍ය පංති සමඟ පැන නගින බැවින්, එය තවමත් පැහැදිලි කිරීමක් අවශ්‍ය යැයි මම සිතමි. එවැනි අනුවාදයක් මත ගොස් ඇති අතර, එය බොහෝ විට වැදගත් නොවේ).

මෙන්න මම මාතෘකාවේ ප්‍රශ්නයට පිළිතුරු දීමට උත්සාහ කරමි: අත්තනෝමතික වස්තුවක වර්ගය තීරණය කරන්නේ කෙසේද? බොහෝ අදහස් හා පිළිතුරු වල isinstance භාවිතා කිරීම හෝ භාවිතා නොකිරීම පිළිබඳ වෙනත් යෝජනා ඉතා හොඳයි, නමුත් මම එම ගැටළු වලට විසඳුම් ලබා නොදෙමි.

type()ප්රවේශය සමඟ ප්රධාන ගැටළුව වන්නේ එය පැරණි විලාසිතාවේ සිද්ධීන් සමඟ නිසි ලෙස ක්රියා නොකිරීමයි :

class One:
    pass

class Two:
    pass


o = One()
t = Two()

o_type = type(o)
t_type = type(t)

print "Are o and t instances of the same class?", o_type is t_type

මෙම ස්නිපටය ක්‍රියාත්මක කිරීමෙන් ප්‍රති yield ල ලැබෙනු ඇත:

Are o and t instances of the same class? True

බොහෝ දෙනා අපේක්ෂා කරන දේ එය නොවන බව මම තර්ක කරමි.

මෙම __class__ප්රවේශය නිරවද්යතාවය සඳහා වඩාත් සමීප වේ, නමුත් එය එක් තීරණාත්මක අවස්ථාවක වැඩ නැහැ: සමත් වීම විට වස්තුව පැරනි පන්නයේ වේ පන්තියේ අය වැනි වස්තූන් විශේෂණය නොමැති බැවින්, (! නොවන උදාහරණයක්).

එවැනි නීත්‍යානුකූල ප්‍රශ්නයක් ස්ථාවර ආකාරයකින් තෘප්තිමත් කළ හැකි යැයි සිතිය හැකි කුඩාම කේතයේ කොටස මෙයයි:

#!/usr/bin/env python
from types import ClassType
#we adopt the null object pattern in the (unlikely) case
#that __class__ is None for some strange reason
_NO_CLASS=object()
def get_object_type(obj):
    obj_type = getattr(obj, "__class__", _NO_CLASS)
    if obj_type is not _NO_CLASS:
        return obj_type
    # AFAIK the only situation where this happens is an old-style class
    obj_type = type(obj)
    if obj_type is not ClassType:
        raise ValueError("Could not determine object '{}' type.".format(obj_type))
    return obj_type

5

isinstance භාවිතා කිරීමට ප්‍රවේශම් වන්න

isinstance(True, bool)
True
>>> isinstance(True, int)
True

නමුත් ටයිප් කරන්න

type(True) == bool
True
>>> type(True) == int
False

3

පෙර පිළිතුරු collections.abcවලට අමතරව, තාරාවන්ගේ යතුරු ලියනය සඳහා අනුපූරක වියුක්ත පාදක පන්ති (ඒබීසී) කිහිපයක් අඩංගු බව සඳහන් කිරීම වටී .

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

isinstance(my_obj, list)

ඔබට හැකිය, ඔබ සතුව ඇති වස්තුව අයිතම ලබා ගැනීමට ඉඩ දෙන්නේ දැයි බැලීමට පමණක් ඔබ කැමති නම්, භාවිතා කරන්න collections.abc.Sequence:

from collections.abc import Sequence
isinstance(my_obj, Sequence) 

අයිතම ලබා ගැනීමට, සැකසීමට සහ මකා දැමීමට (එනම් විකෘති අනුපිළිවෙලට) ඉඩ දෙන වස්තූන් කෙරෙහි ඔබ දැඩි උනන්දුවක් දක්වන්නේ නම් , ඔබ තෝරා ගනු collections.abc.MutableSequenceඇත.

වෙනත් බොහෝ ABCs, එහි අර්ථ නිරූපනය කර ඇත Mappingසිතියම්, ලෙස භාවිතා කළ හැකි බව වස්තූන් සඳහා Iterable, Callable, පට ආදිය. මේ සියලු පිළිබඳ සම්පූර්ණ ලැයිස්තුවක් ද දැක ගත හැක සඳහා ලේඛගතකිරීම collections.abc.


1

පොදුවේ ඔබට පන්තියේ නම සහිත වස්තුවකින් නූලක් උකහා ගත හැකිය,

str_class = object.__class__.__name__

සංසන්දනය සඳහා එය භාවිතා කිරීම,

if str_class == 'dict':
    # blablabla..
elif str_class == 'customclass':
    # blebleble..

1

බොහෝ ප්‍රායෝගික අවස්ථාවන්හිදී භාවිතා කිරීම වෙනුවට typeහෝ isinstanceඔබට භාවිතා කළ හැකිය @functools.singledispatch, එය සාමාන්‍ය ශ්‍රිත නිර්වචනය කිරීම සඳහා භාවිතා කරයි ( විවිධ වර්ග සඳහා එකම ක්‍රියාකාරිත්වය ක්‍රියාත්මක කරන බහු ශ්‍රිතයන්ගෙන් සමන්විත ශ්‍රිතය ).

වෙනත් වචන වලින් කිවහොත්, ඔබට පහත සඳහන් කේතයක් ඇති විට එය භාවිතා කිරීමට ඔබට අවශ්‍ය වනු ඇත:

def do_something(arg):
    if isinstance(arg, int):
        ... # some code specific to processing integers
    if isinstance(arg, str):
        ... # some code specific to processing strings
    if isinstance(arg, list):
        ... # some code specific to processing lists
    ...  # etc

එය ක්‍රියාත්මක වන ආකාරය පිළිබඳ කුඩා උදාහරණයක් මෙන්න:

from functools import singledispatch


@singledispatch
def say_type(arg):
    raise NotImplementedError(f"I don't work with {type(arg)}")


@say_type.register
def _(arg: int):
    print(f"{arg} is an integer")


@say_type.register
def _(arg: bool):
    print(f"{arg} is a boolean")
>>> say_type(0)
0 is an integer
>>> say_type(False)
False is a boolean
>>> say_type(dict())
# long error traceback ending with:
NotImplementedError: I don't work with <class 'dict'>

අතිරේක වශයෙන් අපට එකවර වර්ග කිහිපයක් ආවරණය කිරීම සඳහා වියුක්ත පන්ති භාවිතා කළ හැකිය :

from collections.abc import Sequence


@say_type.register
def _(arg: Sequence):
    print(f"{arg} is a sequence!")
>>> say_type([0, 1, 2])
[0, 1, 2] is a sequence!
>>> say_type((1, 2, 3))
(1, 2, 3) is a sequence!

0

type()වඩා හොඳ විසඳුමක් isinstance(), විශේෂයෙන් booleans:

Trueහා Falseපමණක් බව මධ්යන්ය මූල පද ඇත 1හා 0උත්කර්ෂවත් අන්දමින් දී. මේ අනුව,

isinstance(True, int)

සහ

isinstance(False, int)

දෙදෙනාම ආපසු පැමිණේ True. බූලියන් දෙකම පූර්ණ සංඛ්‍යාවක් සඳහා උදාහරණයකි. type()කෙසේ වෙතත්, වඩාත් දක්ෂ ය:

type(True) == int

ප්‍රතිලාභ False.


0

සම්පුර්ණත්වය සඳහා, නිදසුනක් නොවන උප වර්ගයක් වර්ග පරීක්ෂා කිරීම සඳහා සමස්ථානික ක්‍රියා නොකරනු ඇත . එය පරිපූර්ණ අර්ථයක් ඇති නමුත්, පිළිතුරු කිසිවක් (පිළිගත් පිළිතුර ඇතුළුව) එය ආවරණය නොකරයි. ඒ සඳහා නිකුත් කිරීමේ පන්තිය භාවිතා කරන්න .

>>> class a(list):
...   pass
... 
>>> isinstance(a, list)
False
>>> issubclass(a, list)
True
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.