Рубрики
Без рубрики

Как больше не бояться Python

Автор оригинала: Neil Kakkar.

Погружение в языковую справочную документацию

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

Само собой разумеется, я не превратился в отличный разработчик. Я застрял. Затем, в один прекрасный день, он просто нажал. Я понял, что делал это неправильно. Изучение синтаксиса должно быть наименьшее из моих проблем. Что важно все остальное о языке. Что именно все это? Читать дальше.

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

Эта статья больше понимания того, как все работает в Pythonland – в отличие от того, как выучить Python. Вы найдете много каких-либо источников обучения онлайн.

То, что я не нашел в Интернете, был единственным источником общего «готы» в Python. Источник, объясняющий, как работает языком. Это попытки решить эту проблему. Я думаю, что я придумал, что это так много!

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

Без дальнейшего ADO, здесь мы идем.

Модель данных

Объекты, значения и типы

Объекты являются абстракция Python для данных.

Каждый объект имеет свой уникальный фиксированный личность , фиксированный Тип и а ценность Отказ

«Исправлено» означает личность и Тип от Объект никогда не может измениться.

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

Мутамность определяется Тип :

  • Числа, строки и кортежи неизмерены
  • Списки и словари смены

Личность объектов можно сравнить через это оператор.

ID () Возвращает личность

Тип () Возвращает тип

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

Простой перевод: неизменность не совпадает с неизменным значением. В примере ниже кортеж это неизменный , пока это ценность продолжает меняться (как список меняется).

Пример:

>>> t = ("a", [1]) # a tuple of string and list
>>> id(t)
4372661064
>>> t
('a', [1])
>>> type(t)

>>> t[1]
[1]
>>> t[1].append(2)
>>> t
('a', [1, 2])
>>> id(t)
4372661064
>>> type(t)

В кортеже неизменяется, хотя он содержит сметный объект, список.

Сравните это с строкой, где изменение существующего массива изменяет объект (поскольку строки неизменяются).

>>> x = "abc"
>>> id(x)
4371437472
>>> x += "d"
>>> x
'abcd'
>>> id(x)
4373053712

Здесь имя, х связан с другим объектом типовой строки. Это также меняет свой идентификатор.

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

Встроенные типы

Python приходит с несколькими Встроенные типы :

Никто

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

>>> type(None)

Числа

Это коллекция абстрактных базовых классов, используемых для представления чисел. Они не могут быть созданы, а int , плавать наследует от Числа. Промежуточное количество Отказ

Они создаются числовыми литералами и арифметическими операциями. Возвращенные объекты неизменяются, как мы видели. Следующий список примеров сделает это понятно:

>>> a = 3 + 4
>>> type(a)

>>> isinstance(a, numbers.Number)
True
>>> isinstance(a, numbers.Integral)
True
>>> isinstance(3.14 + 2j, numbers.Real)
False
>>> isinstance(3.14 + 2j, numbers.Complex)
True

Последовательности

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

Лен () Возвращает длину последовательностей. Когда длина N Набор индекса имеет элементы из 0 ... N-1 Отказ Тогда ITH-элемент выбран по SEQ [I-1] Отказ

Для последовательности л , вы можете выбрать элементы между индексами, используя SliCing: л [i: j] Отказ

Существует два типа последовательностей: мультипликационные и неизменные.

  • Неподвижные последовательности включают в себя: строки, кортежи и байты.
  • Союзные последовательности включают в себя: списки и байтовые массивы

Набор

Они представляют неупорядоченные, конечные наборы уникальных, неизменных объектов. Они не могут быть проиндексированы, но могут быть итерация. Лен () по-прежнему возвращает количество предметов в наборе.

Существует два типа наборов: Musable и неизменной.

  • Создается мультиптарный набор Установить () Отказ
  • Immutable набор создан Frozenset () Отказ

Сопоставления

Словарь

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

Это означает Frozenset может быть ключом словаря тоже!

Модули

Объект модуля является основной организационной единицей в Python. Пространство имен реализуется как словарь. Атрибутные ссылки – это поиску в этом словаре.

Для модуля м Словарь только для чтения, доступ к … м .__ Dict__ Отказ

Это обычный словарь, чтобы вы могли добавить к нему ключи!

Вот пример, с Дзэн Питона :

Мы добавляем нашу пользовательскую функцию, Рисунок () к модулю это Отказ

>>> import this as t
>>> t.__dict__
{'__name__': 'this', '__doc__': None, '__package__': '',
.....
.....
's': "Gur Mra bs Clguba, ol Gvz Crgref\n\nOrnhgvshy vf orggre guna
vqrn.\nAnzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!",
'd': {'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 
'u': 'h', 'v': 'i', 'w': 'j', 'x': 'k', 'y': 'l', 'z': 'm'},
'c': 97,
'i': 25
}
>>> def figure():
...   print("Can you figure out the Zen of Python?")
... 
>>> t.fig = figure
>>> t.fig()
Can you figure out the Zen of Python?
>>> t.__dict__
{'__name__': 'this', '__doc__': None, '__package__': '',
.....
.....
's': "Gur Mra bs Clguba, ol Gvz Crgref\n\nOrnhgvshy vf orggre guna
vqrn.\nAnzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!",
'd': {'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 
'u': 'h', 'v': 'i', 'w': 'j', 'x': 'k', 'y': 'l', 'z': 'm'},
'c': 97,
'i': 25
'fig': 
}
>>> print("".join([t.d.get(c, c) for c in t.s]))
The Zen of Python, by Tim Peters
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 позволяет Перегрузка оператора Отказ

Классы имеют специальные имена функций – методы, которые они могут реализовать для использования определенных операторов Python. Это включает в себя нарезку, арифметические операции и подписки.

Например, __getitem __ () относится к подписям. Следовательно, х [я] эквивалентно Тип (х) .__ GetITem __ (x, i) Отказ

Следовательно, использовать оператор [] на классе SomeClass : Вам нужно определить __getitem __ () в SomeClass Отказ

>>> class operatorTest(object):
...     vals = [1,2,3,4]
...     def __getitem__(self, i):
...         return self.vals[i]
... 
>>> x = operatorTest()
>>> x[2]
3
>>> x.__getitem__(2)
3
>>> type(x)

>>> type(x).__getitem__(x,2)
3
>>> OperatorTest.__getitem__(x,2)
3

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

Аналогично, __str __ () Функция Определяет выход, когда str () Метод вызывается на объекте вашего класса.

Для сравнения операций, имена специальных функций:

  • объект .__ LT __ (я, другие) для & LT; (“меньше, чем”)
  • объект .__ le __ (я, другие) для & l t; = (“меньше или равно”)
  • Объект .__ EQ __ (Self, Другое) для == (“равно”)
  • объект .__ ne __ (я, другие) для ! = («Не равен»)
  • объект .__ GT __ (Self, Другое) для & GT; (“больше чем”)
  • объект .__ GE __ (я, другие) для и г t; = (“больше или равно”)

Так например, X & L T; Y называется как х .__ LT__ (Y)

Есть также Специальные функции арифметических операций , как объект .__ Добавить __ (Self, Другое) Отказ

В качестве примера x + y называется как x .__ Добавить __ (Y)

Еще интересное Функция это __er __ () Отказ

Вы называете этот метод, когда вам нужен итератор для контейнера. Возвращает Новый итераторный объект которые могут повторять все объекты в контейнере.

Для сопоставлений он должен итерации по ключам контейнера.

Сам объект итератора поддерживает два метода:

  • iTerator .__ ITER __ () : Возвращает сам объект.

Это делает Итераторы и Контейнеры эквивалентно.

Это позволяет использовать итератор и контейнеры как для использования в для и в заявления.

  • iTerator .__ следующий __ () : Возвращает следующий элемент из контейнера. Если нет дальнейших предметов, поднимает Заставка исключение.
class IterableObject(object):    # The iterator object class
     vals = []
     it = 0
     def __init__(self, val):
         self.vals = val
         it = 0
 
     def __iter__(self):
         return self
 
     def __next__(self):
         if self.it < len(self.vals):
             index = self.it
             self.it += 1
             return self.vals[index]
         raise StopIteration
 
 class IterableClass(object):    # The container class
       vals = [1,2,3,4]
 
       def __iter__(self):
         return iterableObject(self.vals)
>>> iter_object_example = IterableObject([1,2,3])
>>> for val in iter_object_example:
...   print(val)
... 
1
2
3
>>> iter_container_example = IterableClass()
>>> for val in iter_container_example:
...  print(val)
... 
1
2
3
4

Прохладные вещи, верно? Также есть прямой эквивалент в JavaScript.

Контекстные менеджеры также реализованы через перегрузку оператора.

с открытым (именем файла, ‘r’) как f

Открыть (имя файла, 'r') это объект менеджера контекста, который реализует

объект .__ введите __ (я) а также

объект .__ Выход __ (self, exc_type, exc_value, traceback) Все вышеперечисленные три параметра нуль, когда ошибка – Нет Отказ

class MyContextManager(object):
    def __init__(self, some_stuff):
        self.object_to_manage = some_stuff
    def __enter__(self):
        print("Entering context management")
        return self.object_to_manage # can do some transforms too
    
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is None:
            print("Successfully exited")
            # Other stuff to close
>>> with MyContextManager("file") as f:
...     print(f)
... 
Entering context management
file
Successfully exited

Это не полезно – но получает точку. Это делает это полезным в любом случае?

Модель исполнения

Блок – это кусок кода, выполненный в качестве устройства в кадре выполнения.

Примеры блоков включают в себя:

  • Модули, которые являются блоками верхнего уровня
  • Функциональное тело
  • Определение класса
  • Но не для петли и другие контрольные структуры

Помните, как все это объект в Python?

Ну, у вас есть имена связаны с этим Объекты Отказ Эти имена То, о чем вы думаете как переменные.

>>> x
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'x' is not defined

Привязка имени или назначение происходит в блоке.

Примеры привязки имени – они интуитивно понятны:

  • Параметры для функций связаны с именами, определенными в функции
  • Импортные операторы Свяжите имя модуля
  • Определения класса и функции связывают имя к объектам класса/функции
  • Контекстные менеджеры: с ... как f : f – это имя, связанное с ... объект

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

Переменные, используемые в блоке без определения, есть бесплатные переменные.

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

Помните, как для петлей не блокирует? Вот почему итерационные переменные, определенные в петле, доступны после петли, в отличие от C ++ и JavaScript.

>>> for i in range(5):
...   x = 2*i
...   print(x, i)
... 
0 0
2 1
4 2
6 3
8 4
>>> print(x, i)    # outside the loop! x was defined inside.
8 4

Когда имя используется в блоке, он разрешен с использованием ближайшего ограждения.

Например:

>>> name = "outer_scope"
>>> def foo():
...     name = "inner_function" if name == "outer_scope" \
                else "not_inner_function"
... 
>>> foo()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in foo
UnboundLocalError: local variable 'name' referenced before assignment

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

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

Следовательно, когда вы обязательно, имя Имя к объекту "inner_function" : перед привязкой вы проверяете его значение. Правило говорит, что вы не можете ссылаться на него перед привязкой. Именно причина UnsoundLocalError Отказ

Лексический анализ

Python позволяет вам использовать Линейные соединения Отказ Явным образом продолжить линии, используйте обратную косание.

Комментарии не допускаются после соединений линии.

if a < 10 and b < 10 \ # Comment results in SyntaxError
and c < 10: # Comment okay
    return True
else:
    return False

Неявно, соединение линии происходит самостоятельно, когда элементы внутри скобок. Комментарии здесь разрешены.

month_names = ['Januari', 'Februari', 'Maart',      # These are the
               'April',   'Mei',      'Juni',       # Dutch names
               'Juli',    'Augustus', 'September',  # for the months
               'Oktober', 'November', 'December']   # of the year

Отступ

Количество пробелов/вкладок в Отступ не имеет значения, пока он увеличивается для вещей, которые должны быть с отступом. Первая строка не должна быть отступами.

Четыре пробелов правило – это Конвенция, определенная Pep 8: Руководство по стилю Отказ Это хорошая практика, чтобы следовать за этим.

# Compute the list of all permutations of l.
def perm(l):
        # Comment indentation is ignored
    if len(l) <= 1:
                  return [l]
    r = []
    for i in range(len(l)):
             s = l[:i] + l[i+1:]     # Indentation level chosen
             p = perm(s)             # Must be same level as above
             for x in p:
              r.append(l[i:i+1] + x) # One space okay
    return r

Есть несколько зарезервированных идентификаторов.

  • _ Для импорта: функции/переменные, начиная с _ не импортированы.
  • __ * __ Для определенных систем имен, определенные реализацией: мы видели несколько из них. ( __str __ () , __er __ () , __add __ () )

Python также предлагает Неявное строковое буквальное согласие

>>> def name():
...   return "Neil" "Kakkar"
...
>>> name()
'Neil Kakkar'

Форматирование строк

Форматирование строки это полезный инструмент в Python.

Строки могут иметь {expr} в строке литерала, где expr это выражение. Оценка экспрессии замещена на месте.

Конверсии могут быть указаны для преобразования результата перед форматированием.

! R звонки rep () , ! S звонки str () и ! A звонки ASCII ()

>>> name = "Fred"
>>> f"He said his name is {name!r}."
"He said his name is 'Fred'."
>>> f"He said his name is {repr(name)}."  # repr() is equiv. to !r
"He said his name is 'Fred'."
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"  # nested fields
'result:      12.35'
# This is same as "{decf:10.4f}".format(decf=float(value))
>>> today = datetime(year=2017, month=1, day=27)
>>> f"{today:%B %d, %Y}"  # using date format specifier
'January 27, 2017'
>>> number = 1024
>>> f"{number:#0x}"  # using integer format specifier
'0x400'

Это очистительный синтаксис для использования str.format ()

Резюме

С этим мы покрыли основные столбы Python. Модель данных объектов, модель выполнения со своими областями и блоками и некоторые биты на строках. Зная, что все это ставит вас впереди каждого разработчика, который знает только синтаксис. Это более высокое число, чем вы думаете.

В части 2 мы посмотрим на объектные классы и функции.

Чтобы узнать больше, вот отличная книга – Эффективный Python Отказ [Партнерская ссылка – спасибо за поддержку!]

Другие истории в этой серии:

Наслаждался этим? Не пропустите пост снова – подпишитесь на мой список рассылки!