Питон: Пожалуйста, будьте осторожны в этих местах
python - очень интересный язык. Он предоставляет множество очень удобных стандартных библиотек и множество встроенных команд, которые нам позволяют легко выполнять задачи. Но слишком много хорошего вызывает страх выбора, и мы не можем хорошо использовать эту стандартную библиотеку и ее основные структуры. Ниже перечислены некоторые простые и эффективные ловушки для новичков в Python.
Это вопрос, который постоянно поднимается в StackOverflow. Как бывает, когда ваш идеальный код работает на чужом компьютере, поэтому вам нужно проверить, соответствует ли ваша версия Python. Убедитесь, что код работает на версии Python, которые вы знаете.
$ python --version
Python 2.7.9
Управление версиями python
pyenv - отличный инструмент для управления версиями на Python. К сожалению, он работает только на*на системах nix. на Mac OS, вы можете просто установить pyenv с помощью brew install, на системах Linux, есть автоинсталлятор automatic installer
Многие люди хвастаются, что я могу решить все проблемы с помощью одной строки кода, даже если их код менее эффективен, чем обычный, и этот код будет труднее читать, и даже будет искажен. Например:
l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]
Честно говоря, я сам написал этот код, чтобы объяснить это. Но я действительно видел, как многие люди делают это. Если вы просто добавляете что-то в список или набор, чтобы показать, как решить сложную проблему, вы можете потерять деньги.
Однострочный код - это не очень большое достижение, хотя иногда он кажется особенно умным. Хороший код - это простой, но с большим вниманием к эффективности и легкости чтения.
Это более тонкий вопрос, который иногда может застать вас врасплох.
>>> { n for n in range(10) if n % 2 == 0 }
{0, 8, 2, 4, 6}
>>> type({ n for n in range(10) if n % 2 == 0 })
Приведенный выше пример иллюстрирует это. Их отличие в том, что множество не имеет повторяющихся значений и не упорядочено. {} обычно считается пустым множеством, но это не так, это пустой дикт.
>>> {}
{}
>>> type({})
Итак, если мы хотим инициализировать пустое множество, то мы используем просто set ().
>>> set()
set()
>>> type(set())
Обратите внимание, что пустое множество может быть представлено как set (), но множество, содержащее элементы, должно быть определено как set ().[1, 2])
GIL (Global Interpreter Lock) означает, что только одна нить может быть запущена в программе Python в любое время. Это означает, что мы не можем создать нить и ожидать, что она будет работать параллельно. То, что интерпретатор Python фактически делает, - это быстро переключается между различными работающими нитями.
Многие пытаются объяснить Python тем, что это все настоящие потоки. 3 Это действительно так, но это не меняет того факта, что Python обрабатывает потоки не так, как вы ожидаете.
Определенное решение - использовать модуль мультипроцессинга. Класс процессов, предоставляемый модулем мультипроцессинга, в основном хорошо покрывает расхождения. Однако, расхождения намного дороже, чем потоки.
Однако эта проблема встречается не в каждой программе Python. PyPy-stm является примером реализации Python, которая не подвержена влиянию GIL. Реализации, построенные на других платформах, таких как JVM (Jython) или CLR (IronPython), не имеют проблем с GIL.
В конце концов, будьте осторожны с использованием этих классов, потому что вы можете получить не то, что хотите.
В Python 2 существует два типа классов: отсталые и новые. Если вы используете Python 3, то вы используете стандартные отсталые классы. Для того, чтобы убедиться, что вы используете новые в Python 2 классы, вам нужно унаследовать object или любой новый класс, который вы создаете, который не всегда наследует встроенные инструкции int или list.
class MyNewObject(object): # stuff here
Эти новые класса решат некоторые очень основные проблемы, которые возникали в старых классах, если вы заинтересованы в документации.
Вот некоторые из самых распространенных ошибок новичков:
for name_index in range(len(names)):
print(names[name_index])
Очевидно, что нет необходимости использовать len, и перемещение по списку можно сделать с помощью очень простых предложений:
for name in names:
print(name)
Кроме того, существует множество других инструментов, которые помогут вам упростить повторение. Например, zip может быть использован для прохождения через два списка:
for cat, dog in zip(cats, dogs):
print(cat, dog)
Если мы хотим учитывать индексацию и перечень переменных, мы можем использовать enumerate
for index, cat in enumerate(cats):
print(cat, index)
В itertools есть много функций, которые вы можете выбрать. Если вitertools есть функция, которую вы хотите, это удобно. Но не используйте ее слишком много, чтобы использовать ее.
Недостаточное использование itertools заставило одного из главных героев StackOverflow потратить много времени на его устранение.
Использование переменных параметров по умолчанию
Я видел много таких:
def foo(a, b, c=[]):
# append to c
# do some more stuff
Не используйте переменные параметры по умолчанию, а не следующее:
def foo(a, b, c=None):
if c is None:
c = []
# append to c
# do some more stuff
Вот пример, который поможет нам понять это наглядно:
In[2]: def foo(a, b, c=[]):
... c.append(a)
... c.append(b)
... print(c)
...
In[3]: foo(1, 1)
[1, 1]
In[4]: foo(1, 1)
[1, 1, 1, 1]
In[5]: foo(1, 1)
[1, 1, 1, 1, 1, 1]
Тот же c цитируется снова и снова каждый раз, когда эта функция вызывается. Это может привести к очень ненужным последствиям.