При формировании очередного выпуска для pythondigest.ru натолкнулся на заметку египетского программиста Mohammad Tayseer с призывом постигать душу Python.
По себе знаю, что переход с друхих языков на Python тянет за собой не всегда правильные привычки, поэтому для себя и для Вас перевожу заметку египтянина. Перевожу как могу, поэтому приветствую поправки.
- - -
Mohammad Tayseer
Нравится вам это или нет, вы уже используюте различные языки каждый день: SQL, JavaScript, Python, C ++ и другие. Мудрость гласит, что обучение разных языков программирования поможет вам стать лучшим программистом. Но многие не становятся от этого лучшими, и считают что это пустая трата времени.
После многолетнего общения и работы со многими из них, я понял, что они учат синтаксис языка, возможно, некоторые библиотеки, но они не постигают душу языка.
Примеры:
# Плохо: Вы должны дочитать код до конца чтобы понять его
img.find('.jpg') != -1
img.find('.jpg') >= 0
# Хорошо: Читать легче
'.jpg' in img
'.jpg' not in img
# Плохо. Жестко указанная позиция
img[-4:] == '.jpg'
# Хорошо. Строка может быть любой длины
img.endswith('.jpg')
# Плохо.
(img.endswith('.jpg') or img.endswith('.jpeg') or img.endswith('.png') or
img.endswith('.gif')
# Хорошо: Использование возможностей языка для лаконичности
img.endswith((".jpg", ".jpeg", ".png", ".gif"))
# Плохо
path == 'js' or path == 'css' or path == 'img' or path == 'font' or path == 'fonts'
# Хорошо. Тоже что и в предыдущем примере, лаконичность за счет использования возможностей языка.
path in ('js', 'css', 'img', 'font', 'fonts')
# Плохо.
(os.path.exists(os.path.join(path, "space")) or
os.path.exists(os.path.join(path, "bucket")) or
os.path.exists(os.path.join(path, "actor"))
# Хорошо. Компактность. Лучшая читаемость. Список может быть перемещен в другой файл
any(os.path.exists(os.path.join(path, item)) for item in ["space", "bucket", "actor"])
# Плохо.
for i in range(len(lst)):
elt = lst[i]
print i, elt
# Хорошо. Использованы встроенные функции языка
for i, elt in enumerate(lst):
print i, elt
# Плохо
print 'Hello ', name, '. You are ', age, ' years old'
# Хорошо. Отражает структуру последующего вывода
print 'Hello {name}. You are {age} years old'.format(name=name, age=age)
# Плохо.
if not (key in dict):
print 'Key missing'
# Хорошо. Более читаемый код.
if key not in dict:
print 'Key missing'
# Плохо
s = names[0]
for name in names[1:]:
s += ', ' + name
# Хорошо. Не возникает проблемы с одним элементом. Работает быстрее
s = ', '.join(names)
# Плохо.
# Ищет если array1 является подмножеством array2
is_subset = True
for x in array1:
found = False
for y in array2:
if x == y:
found = True
break
if not found:
is_subset = False
break
# Хорошо. 2 строки вместо 10!
def subset_of(array1, array2):
return set(array1).issubset(array2)
# Плохо.
if case_sensitivity.lower() == 'sensitive':
matcher = fnmatch.fnmatchcase
elif case_sensitivity.lower() == 'insensitive':
def matcher(fname, pattern):
return fnmatch.fnmatchcase(fname.lower(), pattern.lower())
else:
matcher = fnmatch.fnmatch
# Хорошо. Код может быть перемещен в другой файл.
matchers = {
'sensitive': fnmatch.fnmatchcase
'insensitive': lambda fname, pattern: fnmatch.fnmatchcase(fname.lower(), pattern.lower())
}.get(case_sensitivity.lower(), fnmatch.fnmatch)
Оригинал заметки на английском:
Комментарии