Onko olemassa yksinkertainen tapa määrittää, onko muuttuja lista, sanakirja vai jokin muu? Saan takaisin objektin, joka voi olla kumpaakin tyyppiä, ja minun on pystyttävä erottamaan se toisistaan.
Voit saada objektin tyypin käyttämällä sisäänrakennettua type()
-funktiota. Jos annat objektin ainoana parametrina, se palauttaa kyseisen objektin tyyppiobjektin:
>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})
<type 'dict'>
>>> type([])
<type 'list'>
Tämä toimii tietysti myös mukautetuille tyypeille:
>>> class Test1 (object):
pass
>>> class Test2 (Test1):
pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True
Huomaa, että type()
palauttaa vain objektin välittömän tyypin, mutta ei pysty kertomaan tyyppiperinnöstä.
>>> type(b) is Test1
False
Tätä varten kannattaa käyttää funktiota isinstance
. Tämä toimii tietysti myös sisäänrakennetuille tyypeille:
>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True
isinstance()
on yleensä suositeltavin tapa varmistaa objektin tyyppi, koska se hyväksyy myös johdetut tyypit. Ellet siis oikeasti tarvitse tyyppiobjektia (jostain syystä), isinstance()
:n käyttö on parempi kuin type()
:n käyttö.
Myös isinstance()
:n toinen parametri hyväksyy tyyppien tuplan, joten on mahdollista tarkistaa useita tyyppejä kerralla. isinstance
palauttaa true-tuloksen, jos objekti kuuluu johonkin näistä tyypeistä:
>>> isinstance([], (tuple, list, set))
True
Pythonista olisi ehkä parempi käyttää try
...except
-lohkoa. Tällä tavalla, jos sinulla on luokka, joka on kuin lista tai dict, se käyttäytyy oikein riippumatta siitä, mikä sen tyyppi todellisuudessa on.
Selventääkseni, suositeltava tapa "erottaa" muuttujatyypit toisistaan on niin sanottu duck typing: niin kauan kuin metodit (ja paluutyypit), joihin muuttuja vastaa, ovat sitä, mitä aliohjelmasi odottaa, kohtele sitä niin kuin odotat sen olevan. Jos sinulla on esimerkiksi luokka, joka ylikuormittaa sulkuoperaattorit getattr
ja setattr
, mutta käyttää jotakin hassua sisäistä järjestelmää, sen olisi asianmukaista käyttäytyä kuin sanakirja, jos se yrittää emuloida sitä.
Toinen ongelma type(A) is type(B)
-tarkistuksessa on se, että jos A
on B
:n aliluokka, se antaa tulokseksi false
, kun ohjelmallisesti toivoisit sen olevan true
. Jos objekti on listan aliluokka, sen pitäisi toimia kuten listan: tyypin tarkistaminen toisessa vastauksessa esitetyllä tavalla estää tämän. (isinstance
toimii kuitenkin).