Python'daki kanonik tipli yoxlama metodu nədir?

Verilən bir obyektin müəyyən bir növü olub olmadığını yoxlamaq üçün ən yaxşı üsul nədir? Bir obyektin müəyyən bir növdən miras alındığını yoxlamaq üçün necə?

Gəlin o bir obyekt var. Bu bir str nədir?

984
30 сент. Sep 30-də Herge tərəfindən təyin olundu 2008-09-30 14:00 '08 saat 02:00 'da, 2008-09-30 14:00' de
@ 9 cavab

O, str və ya str altındakı o nümunə olub olmadığını yoxlamaq üçün, isinstance istifadə edin (bu, "kanonik" üsul olacaq):

 if isinstance(o, str): 

O tipi tam str (alt sinfi istisna olmaqla) olub olmadığını yoxlamaq üçün:

 if type(o) is str: 

Aşağıdakılar da işləyir və bəzi hallarda faydalı ola bilər:

 if issubclass(type(o), str): 

Müvafiq məlumat üçün Python Kitabxanasında Yerləşdirilmiş funksiyalara baxın.

Digər bir qeyd: bu halda, Python 2 istifadə edirsinizsə, istifadə edə bilərsiniz:

 if isinstance(o, basestring): 

çünki Unicode strings də ( unicode str strings və alt və strunicode basestring alt siniflər basestring ). Qeyd edək ki, basestring artıq Python 3-də mövcuddur, burada strings ( str ) və ikili məlumatların ( bytes ) sıx ayrılması mövcuddur.

Bundan əlavə, isinstance siniflər bir isinstance qəbul edir. X (xəta, Unicode) hər hansı bir alt sinifinin nümunəsi olduqda bu, həqiqətə dönəcəkdir:

 if isinstance(o, (str, unicode)): 
1209
30 сент. Cavab Fredrik Johansson tərəfindən verilir 30 sep. 2008-09-30 14:07 '08 saat 14:07 'da 2008-09-30 14:07

Bir obyektin növünü yoxlamaq üçün ən Python yolu onu yoxlamaq deyil.

Python Duck Yazmağa təşviq etdiyinə görə , yalnız try...except etməlisiniz try...except obyekt metodlarını necə istifadə etmək istərdiklərindən try...except . Buna görə funksiyası yazılabilir fayl obyekti axtarırsa, file alt sinfi olub olmadığını yoxlayın, yalnız .write() istifadə edin!

border=0

Əlbəttə, bəzən bu yaxşı abstractions isinstance(obj, cls)isinstance(obj, cls) sizə lazım isinstance(obj, cls) . Amma az istifadə edin.

156
30 сент. Cavab Dan Lenski 30 sep verilir. 2008-09-30 20:40 '08 at 8:40 pm 2008-09-30 20:40

isinstance(o, str) bir növü varsa, true olur.

type(o) is stro yalnız str str. Əgər o , str'den irəli gələn bir növü varsa false qaytarır.

43
30 сент. Herge tərəfindən verilmiş cavab 30 sentyabr 2008-09-30 14:05 '08 saat 02:05 'da 2008-09-30 14:05

Sual verildikdən və cavab alındıqdan sonra Python'a tip ipuçları əlavə edildi . Python tipi göstərişlər, növləri yoxlamaq üçün imkan verir, lakin statik şəkildə yazılmış dillərdə deyil. Python tipi göstərişlər funksiyaları ilə gözlənilən dəlil növlərini funksiyaları ilə əlaqəli iş vaxtında mövcud olan data kimi əlaqələndirir və bu, növləri yoxlamağa imkan verir. Tip ipucu sintaksisinə bir nümunə:

 def foo(i: int): return i foo(5) foo('oops') 

Bu halda, biz foo('oops') üçün səhv çağırılmasını istəyirik, çünki notlandırılmış arqument növü int . Əlavə edilən tip ipucu normal script əməliyyatında bir səhv gətirmir. Lakin, funksiyalar funksiyaya əlavə olunur, digər proqramların sorğularını və tip səhvlərini yoxlamaq üçün istifadə edə biləcəyi gözlənilən növləri təsvir edir.

Tipi səhvləri aşkar etmək üçün istifadə edilə biləcək digər proqramlardən biri mypy :

 mypy script.py script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int" 

( mypy paket menecerinizdən mypy . CPython ilə gəlir deyə düşünmürəm, amma bəzi formalaşma səviyyəsi var görünür).

Tipi yoxlama statik tərtib edilmiş tərtib edilmiş dillərdə növün yoxlanmasından fərqlidir. Çünki Pythonda növlər dinamikdir, tipli yoxlama, istənilən fürsətdə baş verdiyini iddia etsək, düzgün bir proqram üçün - bahalı olan iş vaxtında aparılmalıdır. Açıq tipli çeklər də zəruri olduğundan daha sərt ola bilər və lazımsız səhvlərə gətirib çıxara bilər (məsələn, argument həqiqətən bu list növünə malikdirmi və ya kifayət qədər iterativdir?).

Açıq tipli yoxlamanın üstünlüyü, daha əvvəl səhvləri tutmaq və ördəkdən daha dəqiq səhv mesajlar verə bilməkdir. Duck növü üçün dəqiq tələblər yalnız xarici sənədlərin köməyi ilə ifadə edilə bilər (ümid edirəm ki, bu, hərtərəfli və dəqiqdir) və uyğun olmayan növlərin səhvləri mənşəyindən uzaq ola bilər.

Python tipi göstərişlər, növlərin müəyyənləşdirilməsi və yoxlanılması mümkün olan bir kompromis təklif etməyi nəzərdə tutur, ancaq normal kodun icrası ilə heç bir əlavə xərc yaranmaz.

typing paketi, müəyyən tipləri tələb etmədən istənilən davranışı ifadə etmək üçün tip ipuçlarında istifadə edilə bilən tip dəyişənləri təklif edir. Məsələn, bu davranışlarla hər hansı bir ehtiyacın göstərilməsini tələb etmək üçün istəklər üçün IterableCallable kimi dəyişənləri ehtiva edir.

Tip ipuçları ən Pythonik növü yoxlama metodu olsa da, tez-tez Pythonic növləri yoxlayır və ördək düymələri ilə yazmağa əsaslanmaz. Tipik göstərişlər nisbətən yenidir və münsiflər hələ də Python əsaslı həlli olduğundan uzaqlaşırlar. Nisbətən mübahisəsiz, lakin çox ümumi müqayisə: tip ipuçları tətbiq oluna bilən bir sənəd təqdim edir, daha erkən və asanlıqla səhvləri anlamaq, çap zamanı daxil edilə bilməyən səhvləri tuta bilər və statik olaraq yoxlana bilər (qeyri-adi mənada hələ iş müddətinin xaricindədir). Digər tərəfdən, ördək yazma uzun müddətdir Python olmuşdur, statik yazaraq idrak xərclərini tətbiq etmir, daha az verbli olur və bütün canlı növləri qəbul edir, sonra isə bəziları.

21
06 мая '16 в 19:12 2016-05-06 19:12 cavab Praxeolitic May 06 '16 da 19:12 2016-05-06 19:12 verilir

Burada ördək yazma təhlükəli olduğundan xəbərdar deyil, niyə pis bir nümunədir. Məsələn: Python kodu (ehtimal ki, düzgün çentikin aşağı salınması), bu vəziyyətin sizə lazım olan şeylərə diqqət yetirməklə yola çıxa biləcəyini və bir ördəkə ehtiyacınız olduğunda bomba əldə etməyinizə diqqət yetirin.

 class Bomb: def __init__(self): "" def talk(self): self.explode() def explode(self): print "BOOM!, The bomb explodes." class Duck: def __init__(self): "" def talk(self): print "I am a duck, I will not blow up if you ask me to talk." class Kid: kids_duck = None def __init__(self): print "Kid comes around a corner and asks you for money so he could buy a duck." def takeDuck(self, duck): self.kids_duck = duck print "The kid accepts the duck, and happily skips along" def doYourThing(self): print "The kid tries to get the duck to talk" self.kids_duck.talk() myKid = Kid() myBomb = Bomb() myKid.takeDuck(myBomb) myKid.doYourThing() 
17
26 янв. Cavab 26 yanvarda Dmitri tərəfindən verilir . 2013-01-26 02:54 '13 at 2:54 2013-01-26 02:54
 isinstance(o, str) 

Sənədlərə keçid

12
30 сент. Aleksandr Kojevnikov tərəfindən verilən cavab 30 sentyabr 2008-09-30 14:01 '08 at 2:01 pm 2008-09-30 14:01

Python kimi dinamik bir dil istifadə etməyi düşündüyün ən gözəl şey, həqiqətən bu kimi bir şeyləri yoxlamaq lazım deyil.

Sizin obyektinizə lazım olan üsulları çağırır və AttributeError tuturam. Daha sonra, test üçün bir obyektə istehza kimi müxtəlif vəzifələri yerinə yetirmək üçün metodunuzu digər (görünürlə əlaqəsiz) obyektlərlə zəng etməyə imkan verəcəkdir.

Faylı bir obyekt kimi qaytarır olan urllib2.urlopen() istifadə edərək internetdən məlumat urllib2.urlopen() istifadə urllib2.urlopen() . Bu, öz növbəsində, bir fayldan oxunan demək olar ki, hər hansı bir üsula ötürülə bilər, çünki eyni read() metodunu real fayl kimi həyata keçirir.

Amma əminəm ki, isinstance() istifadə etmək üçün bir vaxt və yer var, əks halda, ehtimal ki, olmazdı :)

6
30 сент. Cavab Will Harding tərəfindən 30 Sentyabrda verilir 2008-09-30 16:33 '08 at 4:33 pm 2008-09-30 16:33

Hugo üçün:

Yəqin ki, list deyil, array deyil, ancaq bu, problemin yoxlanılmasının bütün növünü göstərir - sözügedən obyektin bir siyahı olub-olmadığını bilmək istəmirsinizsə, bu, bir növ ardıcıllığın olub-olmadığını bilmək, yaxud tək bir obyektdirsə. Buna görə bir ardıcıllıq kimi istifadə edin.

Mövcud bir ardıcıllığa bir obyekt əlavə etmək istəyirsinizsə, yaxud bir obyektin ardıcıllığı varsa, hamısını əlavə edin

 try: my_sequence.extend(o) except TypeError: my_sequence.append(o) 

Bunun bir hilesi, strings və / və dizgələr sırası ilə işləməsidir - bu çətindir, çünki bir simli tez-tez ayrı bir obyekt kimi baxılır, həm də simvollar sırasıdır. Daha pis, çünki bu, həqiqətən, eyni uzunluğun xətlərinin bir ardıcıllığıdır.

Mən adətən API'ımın dizaynını seçirəm ki, yalnız bir dəyər və ya bir sıra götürür - bu işi asanlaşdırır. Lazım gələrsə, keçdiyinizdə yalnız dəyəriniz ətrafında [ ] qoymaq çətin deyil.

(Bu, () ardıcıllıqla göründükləri üçün strings ilə səhvlərə səbəb ola bilər.)

4
01 авг. Chris Barker tərəfindən verilmiş cavab Aug 01 2012-08-01 19:07 '12 at 19:07 2012-08-01 19:07

Hangi xarakter tipinin təyin olunduğunu yoxlamaq üçün aşağıdakı satırı kontrol edə bilərsiniz:

 def chr_type(chrx): if chrx.isalpha()==True: return 'alpha' elif chrx.isdigit()==True: return 'numeric' else: return 'nothing' chr_type("12) 
-6
06 апр. Venkatesan tərəfindən verilmiş cavab 06 Apr 2017-04-06 11:54 '17 at 11:54 2017-04-06 11:54

Tags bağlı digər suallar və ya bir sual