Они могут работать, но могут работать еще лучше.

По мере практики программирование будет постепенно упрощаться, но суть в том, что

программирование сложно.

Это может быть еще более затруднено из-за неудачного сочетания предположений и самостоятельного решения проблем. Особенно без наставника может быть довольно сложно когда-либо узнать, является ли один из способов, которым вы что-то делаете, неправильно. Несомненно, мы все виноваты в том, что в дальнейшем входим в наш код и проводим рефакторинг, потому что все мы постоянно учимся, как делать что-то лучше. К счастью, при правильной осведомленности исправление этих ошибок может сделать вас значительно лучше программиста.

Лучший способ стать большим программистом - это преодолеть ошибки и проблемы. Всегда есть лучший способ сделать что-то, это найти конкретный лучший способ, который является сложной задачей. Легко привыкнуть к тому или иному делу, но иногда нужно немного встряхнуться, чтобы действительно сдвинуться с мертвой точки и стать великим инженером.

Не реализована

Хотя ошибка «Не реализована», вероятно, является одной из наименее распространенных ошибок в этом списке, я думаю, что важно сделать напоминание. Возбуждение NotImplemented в Python не вызовет ошибку NotImplemented, а вместо этого вызовет ошибку типа. Вот функция, которую я написал, чтобы проиллюстрировать это:

def implementtest(num):
    if num == 5:
        raise(NotImplemented)

Каждый раз, когда мы пытаемся запустить функцию, где «num» равно 5, наблюдаем, что происходит:

Решение вызвать правильное исключение состоит в том, чтобы вызвать NotImplementedError, а не вызывать NotImplemented. Для этого я модифицировал нашу функцию:

def implementtest(num):
    if num == 5:
        raise(NotImplemented)
    if num == 10:
        raise(NotImplementedError('This is the right way!'))

И запуск этого даст нам правильный результат:

Изменяемые значения по умолчанию

(В этом я был виноват)

Аргументы по умолчанию в Python оцениваются один раз, и оценка происходит, когда выполняется определение функции. Учитывая, что эти аргументы оцениваются один раз, каждый входящий элемент используется в каждом вызове, что означает, что данные, содержащиеся в переменной, изменяются каждый раз, когда к ним обращаются внутри функции.

def add(item, items=[]):
    items.append(item)

Вместо этого нам следует установить значение нашего параметра равным нулю и добавить условие для изменения списка, если он не существует.

def add(item, items=None):
    if items is None:
        items = []
    items.append(item)

Хотя это в основном относится к статистической / DS / ML-стороне пользователей Python, наличие неизменяемых данных универсально важно в зависимости от обстоятельств.

Глобальные переменные

Внутри объектно-ориентированного языка программирования количество глобальных переменных должно быть сведено к минимуму. Тем не менее, я думаю, что это утверждение важно снабдить подзаголовком, объяснив, что глобальные переменные, безусловно, необходимы и вполне приемлемы в некоторых ситуациях. Прекрасным примером этого является наука о данных, где на самом деле происходит ограниченное количество объектно-ориентированного программирования, а Python используется более функционально, чем обычно.

Глобальные переменные могут вызвать проблемы с именованием и конфиденциальностью, когда несколько функций вызывают и полагаются на одно и то же значение. Отличный пример глобальной переменной, которую я бы сказал, это нормально, - это что-то вроде пути к файлу, особенно та, которая предназначена для упаковки вместе с вашим файлом Python. Даже при написании класса Gtk и перемещении построителя графического пользовательского интерфейса следует делать частные, а не глобальные действия.

Копировать!

Использование копии может быть объективно лучше, чем использование обычного присваивания. Обычные операции присваивания просто будут указывать новую переменную на существующий объект, а не создавать новый объект.

d = 5
h = d

Есть два основных типа копий, которые могут быть выполнены с помощью модуля копирования для Python:

мелкая копия и глубокая копия.

Разница между этими двумя типами копий сводится к типу переменной, которую вы хотите передать через функцию. При использовании глубокого копирования для переменных, содержащихся в одном байте данных, таких как целые числа, числа с плавающей запятой и логические строки или, разница между мелкой копией и глубокой копией не ощущается. Однако при работе со списками, кортежами и словарями я бы рекомендовал всегда выполнять глубокое копирование.

Неглубокая копия создает новый составной объект, а затем (насколько это возможно) вставляет в него ссылки на объекты, найденные в оригинале. Глубокая копия создает новый составной объект, а затем рекурсивно вставляет в него копии объектов, найденных в оригинале. Учитывая эти определения, легко понять, почему вы можете захотеть использовать то или иное для данного типа данных.

import copy
l = [10,15,20]
h = 5
hcopy = copy.copy(h)
z = copy.deepcopy(l)

Чтобы проверить наши результаты, мы можем просто проверить, совпадает ли их идентификатор переменной с условным оператором:

print id(h) == id(hcopy) 
False

В заключение

Чтобы быть хорошим программистом, нужно постоянно совершенствоваться, и, надеюсь, со временем некоторые заблуждения могут быть устранены. Это постепенный и болезненный процесс, но при большом количестве практики и получении дополнительной информации следование простым рекомендациям и подобным советам, безусловно, может быть полезным. Подобное общение с тем, что не нужно делать, обычно способствует отличному общению и делает всех участников отличными программистами, поэтому я думаю, что обсуждение этого, безусловно, может быть полезным, независимо от того, как далеко вы продвинулись в своем бесконечном пути программирования. .