Лоши практики при писане на Python код

  1. Тъй като на днешната лекция стана за малко дума за една-две лоши практики при писане на код на Python реших да ги постна тук, за да не ги забравите.

    1) Пример: https://gist.github.com/861242

    Обяснение: Лоша практика е, защото кодът става по-трудно четим. По-трудно се забелязва кое е условието на if-а (или for, while,...) и къде е операторът, който трябва да се изпълни (в случая print("Hello, World!")). Ако операторите са много няма проблем - те задължително се пишат на отделен ред (с табулация). Но дори операторът да е един, пак е добре да се пише на отделен ред: хем по-четливо, хем по-консистентно с останалата част на кода и най-вече с другите if-ове, for-ове и т.н.

    2) Пример: https://gist.github.com/861311

    Обясненние: Явно IDLE няма проблеми със смесването на една табулация и 4-ри интервала (или с колкото интервала е мапната табулацията). Пробвах и стана.

    Но все пак не е хубаво да ги смесвате, защото някои среди правят разлика между двете и там е малко досадно. Така че бъдете консистентни и още по-добре - използвайте ТАБУЛАЦИЯ.

    3) Пример: https://gist.github.com/861321

    Обяснение: Според мен е доста лоша и досадна практика. Казвам го от личен опит!

    Когато програмирам на c++ ползвам Dev-C++. Но Dev-а има един много странен default навик (поне го имаше преди да намеря проклетата настройка откъдето се фиксва) - сам решава къде да е табулацията. И как го прави - от началото на думите от предишния ред взима позицията на първия символ от втората дума, стига първата дума + интервалите след нея да са повече от 3 (иначе взима началото на третата дума).

    И така, какво се получава. Ако на предния ред имаме for (int i = 0;... и т.н.) табулацията е 4-ри интервала. Засега всичко е наред! Но сега внимавайте! При while (i < 10) табът е 6 интервала. А при if (very_very_very_very_long_variable_name == true) според вас колко интервала таба ще е? Хм? Кой каза половин екран? Непозна! Само една трета от екрана е.

    (Ако се питате от какъв зор трябва променливите да имат дълги имена ще ви отговоря - не трябва да имат дълги имена, а ОПИСАТЕЛНИ имена. Счита се за добра практика (особено ако лично се настрадате) променливите да се кръщават с имена, които описват какво съдържа променливата. Да взмем за пример регистрацията в този сайт. Ако променливата 'a' пази трите имена, променливата 'b' факултетния номер, а 'c' паролата, 'a', 'b', 'c' нищо няма да ви говорят щом забравите за какво са (въпреки че на компютъра му е все тая как си ги кръщавате и дали ги помните или не.). Но ако ги кръстите примерно 'name', 'fk' (или още по-добре 'facultyNumber') и 'password' вече веднага ще си ги спомните за какво са щом ги видите. И за другите, които ще имат щастието/нещастието да ви четат кода ще им е по-ясно.)

    Както сами виждате това беше голям проблем. Особено когато тръгнеш да триеш интервалите един по един.

    P.S. Ако чуете или прочетете на лекции, във форума или на някое друго място за още лоши практики при писане на код - постнете ги тук с поне един пример и обяснение. Ще е хубаво да пишем хубав и четлив код!

    Публикувано преди
  2. Въпрос към админите: Защо ми реже поста? Дори когато пробва да го разделя на два последователни поста пак реже текста на същото място!

    ЕДИТ: Оправих се (< трябваше да се ескейпне). Ако може изтрийте всичките ми постове до този включително без първия. (И сложете едно "Изтрий" до "Редактирай", ако може. Това би улеснило малко нещата.)

    Публикувано преди
  3. Обясненние: Явно Python няма проблеми със смесването на една табулация и 4-ри интервала.

    Всъщност - има. Причината поради, която при тебе е минало е, че редакторът ти просто слага 4 спейса, при натискането на един tab. IDLE прави точно това.

    Ето един пример, чрез vim: http://img218.imageshack.us/img218/4239/indent.png Първият print() е с таб, вторият с четири спейса. Резултатът...

    [vladimiroff@latitude ~]$ python test.py 
      File "test.py", line 3
        print("You're never going to see this, though")
                                                      ^
    IndentationError: unindent does not match any outer indentation level
    [vladimiroff@latitude ~]$ 

    Радвам се, че правилно си осъзнал идеята да бъдем консистентни, но моят(и не само) съвет е да ползваш 4 спейса. Както казахме и на лекцията: PEP 8 казва да ползваме 4 спейса => ползваме 4 спейса.

    Ако държите си мапнете табът да поставя 4 спейса, пак е допустимо. Но да бъдат 4 спейса.

    Публикувано преди
  4. Мерси, направих поправки. И ще е хубаво да преведа (преразкажа) поне част от PEP 8 тук.

    И един въпрос? Защо ползваш vim, а не IDLE или Eclipse или нещо друго от сорта? С какво е по-добра от другите?

    Публикувано преди
  5. Чак да го превеждаш... едва ли има нужда. Ще се говори за тези PEP-ове.

    Относно редактора, в един странен момент ми стана удобен, докато просто си търсех нещо по-функционално от nano за редакция на конфизи из линукс. Позволява максимално персонализиране(customizing), което аз използвам в твърде малка степен и все пак ми е адски приятен.

    Но не използвам само vim, в интерес на истината. Използвам Kate и QtCreator от време на време, макар и двата да са в съответно Vi Input Mode и Vim-style editing. IDLE никога не съм го ползвал, а Eclipse ми е като да трепя пилци с топ, който стреля когато и както си иска(разбирай "Тежък ми е, ръбат и адски неудобен, докато се опитва да мисли вместо мен").

    Това по никакъв начин не трябва да те кара да се чувстваш длъжен да използваш vim. Използвай само това, което ти е удобно. Ние нямаме никакви изисквания към това на какво пишете.

    Публикувано преди
  6. Като става въпрос за "Лоши практики при писане на Python код", на предната лекция в един от слайдовете забелязах конкатенация на стрингове във for цикъл с използване на оператора += .

    Зачудих се, дали в език като Python това става ефективно. Ето малко информация по въпроса: http://skymind.com/~ocrow/python_string/

    Поздрави

    Публикувано преди
  7. @Ангел

    Статията е на N години, където N клони 7... Спомената версия на python е била стара преди 2003та. Кода, който се вика от функциите, сигурно са го пренаписали поне 3 пъти (това да не се приема буквално). Да не говорим че кода му е леко некоректен и никой не му го review-нал.

    Малко по-актуални и по-качествени дискусии (съответно за python 2.4-2.5 и текущия 2.7) има в http://wiki.python.org/moin/PythonSpeed/PerformanceTips#String_Concatenation и https://groups.google.com/group/comp.lang.python/browse_thread/thread/81a950db9cda0310/ (като гледате резултатите там имайте в предвид че timeit май изключва garbage collector-а).

    Python 3 е написан почти от нулата, което значи че не можеш да го сравняваш с 2 версиите. Като port-нах кода от линка на Ангел за python3.2 и го изпълних на 64-bit linux за 10M се оказа че method1 е най-бърз (~2.5s), следван близо от 5 (~3s), 6 (~3.5s) и 4 (~4s) (резултатите не се променяха много от включване на gc).

    При програмиране на python моят съвет е първо да си го напише човек така че да е лесно да го чете/поддържа и чак като се окаже че е бавно да го profile-не, да разбере къде е тапата и да мисли алгоритмични/езикови оптимизации. (е има и изключения)

    Публикувано преди
  8. @Точо Много благодаря за информацията и забележките :)

    Съгласен съм, че е по-добре кодът да бъде лесен да четене и поддръжка. Както беше казал някой от преподавателите - "Python е език, на който се пише бързо, а не такъв, на който написаното върви бързо".

    В случая просто ми беше станало интересно какво се случва "под" string+="string" в Python.

    Публикувано преди

Трябва да сте влезли в системата, за да може да отговаряте на теми.