Niyə boş bir siyahısı təyin edilmir (məsələn, [] = "") bir səhvdir?

Python 3.4, mən yazıram

 [] = "" 

və yaxşı işləyir, heç bir istisna yoxdur. Əlbəttə [] bundan sonra "" bərabər deyil.

 [] = () 

də böyük işlər görür.

 "" = [] 

gözlənildiyi kimi bir istisna səbəb olur

 () = "" 

gözlənildiyi kimi bir istisna səbəb olur. Nə olur?

105
10 мая '15 в 5:41 2015-05-10 05:41 Vardd may ayının 10-da saat 05: 41- də təyin olunub
@ 2 cavablar

Siz bərabərliyi müqayisə etmirsiniz. Siz namizədsiniz .

Python birdən çox hədəf təyin etməyə imkan verir:

 foo, bar = 1, 2 

foobar üçün iki dəyər təyin edir. Lazımdır ki, sağ tərəfdə bir sıra və ya təkrarlama, eləcə də sol tərəfdə bir siyahı və ya bir nişan.

Çalıştığınız zaman:

 [] = "" 

Boş bir sıra (boş sətirlər ardıcıllığı) təyin edilmiş - adların boş siyahısı.

Bu, əsasən, eyni şeydir:

 [foo, bar, baz] = "abc" 

foo = "a" , bar = "b"baz = "c" ilə başa çatdıqda, lakin daha az simvol ilə.

Buna baxmayaraq, bir simli təyin edə bilməzsiniz, buna görə tapşırığın sol hissəsindəki "" heç vaxt işləməyəcək və həmişə sintaksis səhvidir.

Görevlendirme Operatorlarına Baxın:

Tapşırıq operatoru ifadələrin siyahısını nəzərdən keçirir (yadda saxlaya bilərsiniz ki, bu tək bir ifadə və ya bir virgül ilə ayrılan bir siyahısı ola bilər, sonuncusu bir tuple) və hədəf siyahısından hər birinə soldan sağa bir nəticə obyekti verir.

Bir obyektin bir parantez və ya kvadrat mötərizədə qoşulan bir hədəf siyahısına təyin edilməsi, recursively kimi aşağıdakı kimi müəyyən edilir.

Mina üzərinə odaklanın.

Pythonun boş bir siyahı üçün sintaksis səhv atmaması əslində səhv bir hissəsidir! Rəsmi sənədləşdirilmiş qrammatika boş bir hədəf siyahısına icazə vermir və boş () bir səhv alacaqsınız. 23275 səhvinə baxın; Bu zərərsiz bir səhv hesab olunur:

Başlanğıc nöqtəsi çox uzun və zərərsiz olduğunun tanınmasıdır.

Nə üçün boş bir siyahı təyin etmək vacibdir, amma boş bir boşluq üçün deyil?

127
10 мая '15 в 5:43 2015-05-10 05:43 Martijn Pieters tərəfindən cavab 10 May '15 'də saat 05:43' da verildi

Sənədlərdən tapşırıq təlimatlarının qaydalarına uyğun olaraq,

 assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression) 

target list virgülle ayrılmış hədəflər siyahısısə: obyekt hədəf siyahısında hədəf obyektlər kimi eyni sayda element ilə təkrarlanmalı və elementlər soldan sağa müvafiq hədəflərə təyin olunur.

Nesne hədəf siyahısında hədəf obyektlər kimi eyni sayda elementlərlə bir ardıcıllıq olmalıdır və elementlər soldan sağa müvafiq hədəflərə təyin olunur.

Yəni dediyiniz zaman

 [] = "" 

"" iterable (hər hansı bir python simli yinelenebilir) və siyahı maddələrində sıxılmışdır.

Məsələn,

 >>> [a, b, c] = "123" >>> a, b, c ('1', '2', '3') 

Boş bir dize və boş bir siyahısı olduğundan, açmaq üçün heç bir şey yoxdur. Beləliklə səhvlər yoxdur.

Amma bunu sınayın

 >>> [] = "1" Traceback (most recent call last): File "<input>", line 1, in <module> ValueError: too many values to unpack (expected 0) >>> [a] = "" Traceback (most recent call last): File "<input>", line 1, in <module> ValueError: need more than 0 values to unpack 

[] = "1" halda, dəyişənlərin boş bir siyahısının üstündəki "1" lövbərini açmağa çalışırsınız. Buna görə də, "dekompressiya üçün çox dəyərlər (0 gözlənilir)" dan şikayətlənir.

Eyni, [a] = "" halda boş bir simli var, buna görə heç bir şeyi açmaq lazım deyil, ancaq bir dəyişənə açmaq mümkün deyildir. Buna görə o, "açmaq üçün 0-dən çox dəyər tələb olunur" deyə şikayət edir.

Həm də, qeyd etdiyiniz kimi,

 >>> [] = () 

həmçinin səhv gətirmir, çünki () boş bir boşluqdur.

 >>> () () >>> type(()) <class 'tuple'> 

və boş bir siyahıdan açıldığı zaman açmaq üçün heç bir şey yoxdur. Buna görə də heç bir səhv yoxdur.


border=0

Ancaq bunu edərkən

 >>> "" = [] File "<input>", line 1 SyntaxError: can't assign to literal >>> "" = () File "<input>", line 1 SyntaxError: can't assign to literal 

səhv mesajda göstərildiyi kimi, simli bir simli təyin etməyə çalışırsınız. Bu mümkün deyil. Buna görə səhvlər alırsınız. Bu necə deməkdir

 >>> 1 = "one" File "<input>", line 1 SyntaxError: can't assign to literal 

border=0

İçəridə

Bu tapşırığın içərisində əməliyyat UNPACK_SEQUENCE op UNPACK_SEQUENCE ,

 >>> dis(compile('[] = ""', "string", "exec")) 1 0 LOAD_CONST 0 ('') 3 UNPACK_SEQUENCE 0 6 LOAD_CONST 1 (None) 

Burada simli boş UNPACK_SEQUENCE , UNPACK_SEQUENCE 0 dəfə UNPACK_SEQUENCE . Ancaq belə bir şey olduğunda

 >>> dis(compile('[a, b, c] = "123"', "string", "exec")) 1 0 LOAD_CONST 0 ('123') 3 UNPACK_SEQUENCE 3 6 STORE_NAME 0 (a) 9 STORE_NAME 1 (b) 12 STORE_NAME 2 (c) 15 LOAD_CONST 1 (None) 18 RETURN_VALUE 

123 sıra, sağdan sola yığışdırmaq üçün açılır. Beləliklə, yığın üstü 1 , sonrakı 2 , sonuncu isə 3 olacaq. Sonra dəyişənləri soldan ifadə bir-birindən yığın üstünə aparır.


border=0

BTW, Python'da, bir ifadədə birdən çox tapşırıq yerinə yetirə bilərsiniz. Məsələn,

 a, b, c, d, e, f = u, v, w, x, y, z 

bu, əsl dəyərləri bir boğa qurmaq üçün istifadə olunduqdan sonra işləyir və sonra sol tərəfin dəyərlərindən sıxılır.

 >>> dis(compile('a, b, c, d, e, f = u, v, w, x, y, z', "string", "exec")) 1 0 LOAD_NAME 0 (u) 3 LOAD_NAME 1 (v) 6 LOAD_NAME 2 (w) 9 LOAD_NAME 3 (x) 12 LOAD_NAME 4 (y) 15 LOAD_NAME 5 (z) 18 BUILD_TUPLE 6 21 UNPACK_SEQUENCE 6 24 STORE_NAME 6 (a) 27 STORE_NAME 7 (b) 30 STORE_NAME 8 (c) 33 STORE_NAME 9 (d) 36 STORE_NAME 10 (e) 39 STORE_NAME 11 (f) 42 LOAD_CONST 0 (None) 45 RETURN_VALUE 

lakin klassik əvəz üsulu a, b = b, a yığının üst hissəsində elementlərin fırlanma istifadə edir. Yalnız iki və ya üç elementə ROT_TWO , onda ROT_TWO xüsusi ROT_TWOROT_THREE ilə ROT_TWO .

 >>> dis(compile('a, b = b, a', "string", "exec")) 1 0 LOAD_NAME 0 (b) 3 LOAD_NAME 1 (a) 6 ROT_TWO 7 STORE_NAME 1 (a) 10 STORE_NAME 0 (b) 13 LOAD_CONST 0 (None) 16 RETURN_VALUE 
34
10 мая '15 в 5:43 2015-05-10 05:43 10 may 15: 15-da saat 05 : 43 -da cavab verildi