Python: Будьте осторожны в этих местах.

Автор:Илидан, Создано: 2016-12-29 13:46:12, Обновлено:

Python: Будьте осторожны в этих местах.

python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。

  • Игнорируйте версию Python

    Это вопрос, который постоянно поднимается на StackOverflow. Когда ваш идеальный код работает на чужом компьютере, вам нужно проверить, соответствует ли ваша версия python. Убедитесь, что код работает на версии python, о которой вы знаете.

    $ python --version
    Python 2.7.9
    

    Управление версиями Python

    pyenv - хороший инструмент управления версиями python. К сожалению, он работает только на *nix системе. На Mac OS вы можете просто установить pyenv с помощью brew install.

  • Запутавшись в том, чтобы решить все проблемы одной строкой кода

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

    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))]
    

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

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

  • Ошибка в запуске набора

    这是一个更加微妙的问题,有时候会让你措手不及。set推导式起来有点像list推导式.

    >>> { 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()
    >>> type(set())
    

    Обратите внимание, что пустой набор может быть представлен как набор (((), но как набор, содержащий элементы, который должен быть определен как набор (([1, 2])).

  • Неправильное понимание GIL

    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 или любой новый класс, который вы создаете.

    class MyNewObject(object): # stuff here
    

    Эти новые кластеры исправляют некоторые очень основные проблемы, которые возникали в старых классах.

  • Неправильная иерархия

    Некоторые из этих ошибок очень распространены среди новичков:

    for name_index in range(len(names)):
      print(names[name_index])
    

    Очевидно, что нет необходимости использовать len, и на самом деле просмотр списка может быть выполнен с помощью очень простых предложений:

    for name in names:
       print(name)  
    

    Кроме того, существует множество других инструментов, которые помогут вам в работе с упрощением иерархии.

    for cat, dog in zip(cats, dogs):
       print(cat, dog)
    

    Если мы хотим рассматривать переменные в списках индексов и значений, мы можем использовать перечисление.

    for index, cat in enumerate(cats):
       print(cat, index)
    

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

    Из-за злоупотребления 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 цитируется снова и снова при каждом вызове этой функции. Это может иметь некоторые очень ненужные последствия.


Больше