Noteikt objekta veidu?

Vai ir vienkāršs veids, kā noteikt, vai mainīgais ir saraksts, vārdnīca vai kas cits? Es saņemu atpakaļ objektu, kas var būt jebkura tipa, un man ir jāspēj noteikt atšķirību.

Risinājums

Lai iegūtu objekta tipu, varat izmantot iebūvēto funkciju type(). Nosūtot objektu kā vienīgo parametru, tiks atgriezts šī objekta tipa objekts:

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

>>> type([])

Tas, protams, darbojas arī ar pielāgotiem tipiem:

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

Ņemiet vērā, ka type() atgriezīs tikai objekta tiešo tipu, bet nevarēs jums pateikt par tipa pārmantojamību.

>>> type(b) is Test1
False

Lai to aptvertu, jāizmanto funkcija isinstance. Tas, protams, darbojas arī iebūvētajiem tipiem:

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

isinstance() parasti ir vēlamais veids, kā nodrošināt objekta tipu, jo tā pieņem arī atvasinātos tipus. Tātad, ja vien jums patiešām nav nepieciešams tipa objekts (neatkarīgi no iemesla), isinstance() izmantošana ir ieteicamāka nekā type().

Arī otrais parametrs isinstance() pieņem tipu tupli, tāpēc ir iespējams pārbaudīt vairākus tipus vienlaicīgi. Tad isinstance atgriezīs true, ja objekts pieder kādam no šiem tipiem:

>>> isinstance([], (tuple, list, set))
True
Komentāri (16)

To var izdarīt, izmantojot type():

>>> a = []
>>> type(a)

>>> f = ()
>>> type(f)
Komentāri (0)

Pareizāk būtu izmantot try...except bloku. Tādā veidā, ja jums ir klase, kas izskatās pēc saraksta vai dict, tā uzvedīsies pareizi neatkarīgi no tā, kāds ir tās tips reāli.

Lai paskaidrotu, vēlamais veids, kā "noteikt atšķirību" starp mainīgo tipiem, ir kaut kas, ko sauc par duck typing: kamēr metodes (un atgriešanas tipi), uz kurām mainīgais reaģē, ir tādi, kādus sagaida jūsu apakšprogramma, rīkojieties ar to kā ar to, ko jūs sagaidāt, ka tas būs. Piemēram, ja jums ir klase, kas pārslogo iekavju operatorus ar getattr un setattr, bet izmanto kādu smieklīgu iekšējo shēmu, būtu pareizi, ja tā uzvestos kā vārdnīca, ja tā ir tā, ko tā mēģina atdarināt.

Otra problēma ar type(A) is type(B) pārbaudi ir tā, ka, ja A ir B apakšklase, tā tiek novērtēta kā false, lai gan programmatiski varētu cerēt, ka tā būs true. Ja objekts ir saraksta apakšklase, tam būtu jādarbojas kā sarakstam: tipa pārbaude, kā tas parādīts otrā atbildē, to novērsīs. (tomēr isinstance darbosies).

Komentāri (2)