Er der en enkel måde at afgøre, om en variabel er en liste, en ordbog eller noget andet? Jeg får et objekt tilbage, som kan være af begge typer, og jeg skal kunne se forskel.
For at få et objekts type kan du bruge den indbyggede funktion type()
. Hvis du overgiver et objekt som den eneste parameter, returneres objektets typeobjekt:
>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})
<type 'dict'>
>>> type([])
<type 'list'>
Dette virker naturligvis også for brugerdefinerede typer:
>>> class Test1 (object):
pass
>>> class Test2 (Test1):
pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True
Bemærk at type()
kun returnerer objektets umiddelbare type, men ikke kan fortælle dig om typearvning.
>>> type(b) is Test1
False
For at dække dette bør du bruge funktionen isinstance
. Dette virker naturligvis også for indbyggede 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 normalt den foretrukne måde at sikre typen af et objekt på, fordi den også accepterer afledte typer. Så medmindre du faktisk har brug for typeobjektet (uanset årsagen), er det at bruge isinstance()
at foretrække frem for type()
.
Den anden parameter i isinstance()
accepterer også en tupel af typer, så det er muligt at kontrollere for flere typer på én gang. isinstance
vil så returnere sandt, hvis objektet er af en af disse typer:
>>> isinstance([], (tuple, list, set))
True
Det ville måske være mere Python-agtigt at bruge en try
...except
-blok. På den måde vil en klasse, der ligner en liste eller en dict, opføre sig korrekt, uanset hvad dens type virkeligt er, hvis du har en klasse, der ligner en liste eller en dict.
For at præcisere, den foretrukne metode til at "fortælle forskellen" mellem variabel typer er med noget der hedder duck typing: så længe de metoder (og retur typer) som en variabel reagerer på er hvad dit underprogram forventer, behandler du den som det du forventer at den skal være. Hvis du f.eks. har en klasse, der overloader parentesoperatorerne med getattr
og setattr
, men bruger et eller andet sjovt internt skema, ville det være passende for den at opføre sig som en ordbog, hvis det er det, den forsøger at emulere.
Det andet problem med kontrollen type(A) is type(B)
er, at hvis A
er en underklasse af B
, evalueres den til false
, når man programmatisk set ville håbe, at det ville være true
. Hvis et objekt er en underklasse af en liste, skal det fungere som en liste: kontrol af typen som beskrevet i det andet svar forhindrer dette. (isinstance
vil dog virke).