Какие важные языковые особенности (идиомы) Python необходимо изучить на ранней стадии [дубликат]


На этот вопрос уже есть ответ здесь:

Мне было бы интересно узнать, что думает сообщество StackOverflow важные языковые особенности (идиомы) Python. Особенности, которые определили бы программиста как питона.

Python (pythonic) идиома - "выражение кода", которое является естественным или характерным для языка Python.

Кроме того, какие идиомы должны выучить все программисты Python на ранней стадии?

Заранее спасибо

Связанные:

12 18

12 ответов:

Python-это язык, который можно описать следующим образом:

" правила, которые вы можете вписать в ладонь вашей руки с огромным мешком крюки".

Почти все в python следует одним и тем же простым стандартам. Все доступно, изменчиво и легко настраивается. Существует очень мало элементов языкового уровня.

Возьмем, к примеру, встроенную функцию len(data). len(data) работает, просто проверяя Метод data.__len__(), а затем вызывает его и возвращает значение. Таким образом, len() может работать с любым объектом, реализующим метод __len__().
Начните с изучения типов и базового синтаксиса:
  1. Динамические Строго Типизированные Языки
  2. bool, int, float, string, list, tuple, dict, set
  3. утверждения с отступом: "все есть объект"
  4. основные определения функций

Затем переходим к изучению того, как работает python:

  1. импорт и модули (очень просто)
  2. путь питона (sys.путь)
  3. функция dir()
  4. __builtins__

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

  1. итераторы
  2. переопределяет, как __len__ (есть тонны таких)
  3. перечислите понимания и генераторы
  4. классы и объекты (опять же, очень просто, если вы знаете пару правил)
  5. правила наследования python

И как только у вас есть уровень комфорта с этими предметами (с акцентом на то, что делает их питонскими), посмотрите на более конкретные предметы:

  1. многопоточность в Python (Примечание глобальная блокировка интерпретатора)
  2. контекстные менеджеры
  3. доступ к базе данных
  4. файл IO
  5. сокеты
  6. и т. д...

И никогда не забывайте Дзен питона (Тим Питерс)

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Эта страница охватывает все основные идиомы python: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html

Важной идиомой в Python является docstrings.

Каждый объект имеет атрибут__ doc__, который можно использовать для получения справки по этому объекту. Атрибут __doc__ можно задать для модулей, классов, методов и функций следующим образом:

# this is m.py
""" module docstring """

class c:
    """class docstring"""
    def m(self):
        """method docstring"""
        pass

def f(a):
    """function f docstring"""
    return

Теперь, когда вы печатаете help(m), help(m.f) и т.д. он напечатает строку документа в качестве справочного сообщения.

Поскольку это всего лишь часть обычного объектного самоанализа, это может быть использовано системами документооборота, такими как epydoc, или использовано для тестирования единица измерения.

Он также может быть использован для более нетрадиционных (т. е. неидиоматических) применений, таких как грамматики в Dparser.

Еще более интересным для меня является то, что, хотя doc является атрибутом только для чтения для большинства объектов, вы можете использовать их в любом месте, например:

x = 5
""" pseudo docstring for x """

И инструменты документирования, такие как epydoc, могут подобрать их и правильно отформатировать (в отличие от обычного комментария, который остается внутри форматирования кода.

Декораторов получит моего голоса. Где еще можно написать что-то вроде:

def trace(num_args=0):
  def wrapper(func):
    def new_f(*a,**k):
      print_args = ''
      if num_args > 0:
        print_args = str.join(',', [str(x) for x in a[0:num_args]])
      print('entering %s(%s)' %(f.__name__,print_args))
      rc = f(*a,**k)
      if rc is not None:
        print('exiting %s(%s)=%s' %(f.__name__,str(rc)))
      else:
        print('exiting %s(%s)' %(f.__name__))
      return rc
    return new_f
  return wrapper

@trace(1)
def factorial(n):
  if n < 2:
    return 1
  return n * factorial(n-1)
factorial(5)

И получить вывод типа:

entering factorial(5)
entering factorial(4)
entering factorial(3)
entering factorial(2)
entering factorial(1)
entering factorial(0)
exiting factorial(0)=1
exiting factorial(1)=1
exiting factorial(2)=2
exiting factorial(3)=6
exiting factorial(4)=24
exiting factorial(5)=120

Все, что связано с использованием списка.
Генераторы, генераторы и т. д.

С более продвинутой точки зрения, понимание того, как словари используются внутри Python. Классы, функции, модули, ссылки - это всего лишь свойства словаря. После того, как это будет понято, легко понять, как обезьяна патч и использовать мощные методы __gettattr__, __setattr__ и __call__.

Вот один, который может помочь. В чем разница между:

[ foo(x) for x in range(0, 5) ][0]

И

( foo(x) for x in range(0, 5) ).next()

Ответ: во втором примере foo вызывается только один раз. Это может быть важно, если foo имеет побочный эффект, или если итерация, используемая для построения списка, велика.

Лично мне очень нравится синтаксис Python, определяющий блоки кода с помощьюотступа , а не словами "BEGIN" и "END" (как в Microsoft Basic и Visual Basic - мне это не нравится) или с помощью левых и правых скобок (как в C, C++, Java, Perl - мне это нравится).

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

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

Ладно, я слезу со своей мыльницы. ;- )

Две вещи, которые поразили меня как особенно Питонские, были динамическая типизация и различные варианты списков, используемых в Python, особенно кортежи.

Одержимость питона списком можно было бы назвать Лисп-й, но у нее есть свой уникальный вкус. Строка вроде:
return HandEvaluator.StraightFlush, (PokerCard.longFaces[index + 4], 
  PokerCard.longSuits[flushSuit]), []

Или даже

return False, False, False

Просто выглядит как Python и ничего больше. (Технически, вы бы увидели последнее и в Луа, но Луа довольно Питонский в целом.)

Использование подстановок строк:

name = "Joe"
age = 12
print "My name is %s, I am %s" % (name, age)

Когда я не программирую на python, это простое использование-то, чего мне больше всего не хватает.

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

Doctests-это простой текстовый файл, содержащий сеанс интерактивного интерпретатора и текст, подобный этому:

Let's instantiate our class::

>>> a=Something(text="yes")
>>> a.text
yes

Now call this method and check the results::

>>> a.canify()
>>> a.text
yes, I can

Если, например, a. text возвращает что-то другое, тест не пройдет.

Doctests могут быть внутри docstrings или автономных текстовых файлов и выполняются с помощью модуляdoctests . Конечно же ... также доступны более известные модульные тесты.

Я думаю, что онлайн-учебники и книги говорят только о том, как делать вещи, а не о том, как делать вещи наилучшим образом. Наряду с синтаксисом python я думаю, что скорость в некоторых случаях важна.

Python предоставляет способ сравнения функций, фактически два!!

Одним из способов является использование модуля profile, например:

import profile

def foo(x, y, z):
    return x**y % z # Just an example.

profile.run('foo(5, 6, 3)')

Другой способ сделать это-использовать модуль timeit, например:

import timeit

def foo(x, y, z):
    return x**y % z # Can also be 'pow(x, y, z)' which is way faster.

timeit.timeit('foo(5, 6, 3)', 'from __main__ import *', number = 100) 
# timeit.timeit(testcode, setupcode, number = number_of_iterations)