Finnes det en enkel måte å avgjøre om en variabel er en liste, ordbok eller noe annet? Jeg får et objekt tilbake som kan være begge typer, og jeg trenger å kunne se forskjellen.
For å få typen til et objekt kan du bruke den innebygde funksjonen type()
. Hvis du sender et objekt som eneste parameter, returneres objektets type:
>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})
<type 'dict'>
>>> type([])
<type 'list'>
Dette fungerer selvfølgelig også for egendefinerte typer:
>>> class Test1 (object):
pass
>>> class Test2 (Test1):
pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True
Merk at type()
bare vil returnere den umiddelbare typen av objektet, men vil ikke være i stand til å fortelle deg om type nedarving.
>>> type(b) is Test1
False
For å dekke det, bør du bruke funksjonen isinstance
. Dette fungerer selvfølgelig også for innebygde typer:
>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True
isinstance()
er vanligvis den foretrukne måten å sikre typen til et objekt fordi den også aksepterer avledede typer. Så med mindre du faktisk trenger typeobjektet (uansett grunn), er bruk av isinstance()
å foretrekke fremfor type()
.
Den andre parameteren til isinstance()
aksepterer også en tupel av typer, så det er mulig å sjekke for flere typer samtidig. isinstance
vil da returnere true hvis objektet er av en av disse typene:
>>> isinstance([], (tuple, list, set))
True
Det kan være mer Pythonic å bruke en try
...except
blokk. På den måten, hvis du har en klasse som kvakker som en liste, eller kvakker som en dict, vil den oppføre seg riktig uavhengig av hva dens type egentlig er.
For å avklare, den foretrukne metoden for å " fortelle forskjellen " mellom variabeltyper er med noe som kalles duck typing: så lenge metodene (og returtypene) som en variabel reagerer på, er det subrutinen din forventer, behandle den som det du forventer at den skal være. For eksempel, hvis du har en klasse som overbelaster parentesoperatorene med getattr
og setattr
, men bruker en morsom intern ordning, ville det være passende for den å oppføre seg som en ordbok hvis det er det den prøver å etterligne.
Det andre problemet med type(A) er type(B)
-sjekking er at hvis A
er en underklasse av B
, evaluerer den til false
når du programmatisk håper det ville være true
. Hvis et objekt er en underklasse av en liste, skal det fungere som en liste: å sjekke typen som presentert i det andre svaret vil forhindre dette. (isinstance
vil imidlertid fungere).