Някои добри практики

„ Програмиране с Python“, ФМИ

Стефан Кънев & Николай Бачийски

30.05.2007г.

Какво прави следния код?


for x in range(0, 12):
    print arr[x]

А този?


fox index in range(0, NUMBER_OF_MONTHS):
    print monthNames[index]

Писането на код като работа

Когато пишете код, рядко го правите самоцелно. Вместо това, вие опитвате се да решите някакъв реален проблем със собствена логика, терминология и особености. Винаги когато пишете код трябва да се стараете той да отразява много добре този проблем - това го прави много по-четим, по-лесен за поддръжка и по-разбираем от външни хора. Още повече, така вие ясно показвате намерението което вашия код има, вместо да карате читателя да задълбава в особенностите на вашата реализация.

Първо правило: Добри имена на променливи

Променливите обикновенно отговарят за съществуващи обекти/концепции в реалния проблем, който решавате. Това ги прави идеални за комуникиране на идеята на кода. За целта, обаче, се налага да избирате смислени имена.

Типична грешка


# Грешно
temp = sqrt(b ** 2 - 4 * a * c)
x1 = (-b + temp) / (2 * a)
x2 = (-b - temp) / (2 * a)

# По-правилно
discriminant = sqrt(b ** 2 - 4 * a * c)
x1 = (-b + discriminant) / (2 * a)
x2 = (-b - discriminant) / (2 * a)

Лоши имена...


old = readOld()
tupple = getValues(r'c:\')
tup = {}
for t in tupple:
    if old[t] != tupple[t]: continue
    tup.update({t:tupple[t]})

show(tup)
save(tupple)

...и добри имена


oldHashsums = readCachedHashsums()
newHashsums = findHashsums(r'c:\')

changedFiles = {}
for filename in oldHashsums:
    if oldHashsums[filename] != newHashsums[filename]:
        changedFiles[filename] = newHashsums[filename]

reportChanges(changedFiles)
saveHashsums(newHashsums)

Функции / методи / рутини

Рутините са едно от най-често използваните средства в програмирането. И все пак, причините за които има смисъл да създавате рутина са.

Именуване на рутини

При именуване на рутини се съобразявайте внимателно със следните неща.

Кохезия

"Кохезията" на една рутина смътно описва действието й. Като говорим за "добра кохезия" имаме предвид, че една рутина прави едно единствено нещо и го прави добре. Най-силния вид "кохезия" е функционалната. Други видове са:

Неприемлив вид кохезия

Аргументи на рутините

Реакция при грешни параметри на рутината

Лош подход.


def storePerson(name, age, address):
	if not isinsntace(name, str) or len(name) < 6: 
	    raise ValueError("Illegal name")
	if not isinstance(age, int, long) or age < 0:
	    raise ArithmeticError("Illegal age")
	if not hasattr(address, "street") or not hassattr(address, "number"):
	    raise ValueError("Illegal address")
		
	storeData(name, age, address.street, address.number)

Реакция при грешни параметри на рутината (2)

По-добър подход.


def storePerson(name, age, address):
    assert long(age) >= 6
    assert isinstance(name, str) and len(name) >= 6
		
    storeData(name, age, address.street, address.number)

Не ползвайте глобални променливи

Когато пиеше функции, не ползвайте глобални променливи. Ама въобще. Най-честия случай на неправилно ползване на глобавни променливи е когато се употребяват за комуникация между функции. Никога не правете това. В рядките случаи, в които имате нужда от "глобални" обекти правете Singleton-и или thread.local-и.

Не ползвайте goto

В Python няма goto. Ако случайно пишете на друг език, в който има goto, това правило остава - не ползвайте goto.

Не използвайте глупави низове
в съобщенията за грешка

Основната задача на програмиста: да намалява сложността

Подходи за намаляване на сложността: