Проблема с куриным яйцом (ч.1)
Итак, какой "окончательный" базовый класс?
type это метакласс в Python. Все является object на Python, который включает в себя классы, а также их объекты (экземпляры). Класс type - это метакласс class object, и каждый класс (включая type) прямо или косвенно унаследован от object.
Канал в Max🇷🇺
#theory // Just Python
Итак, какой "окончательный" базовый класс?
type это метакласс в Python. Все является object на Python, который включает в себя классы, а также их объекты (экземпляры). Класс type - это метакласс class object, и каждый класс (включая type) прямо или косвенно унаследован от object.
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Проблема с куриным яйцом (ч.2)
Среди object и type нет реального базового класса. Путаница в приведенных выше фрагментах возникает из-за того, что мы думаем об этих взаимосвязях (issubclass и isinstance) в терминах классов Python. Связь между object и type не может быть воспроизведена в чистом python.
Канал в Max🇷🇺
#theory // Just Python
Среди object и type нет реального базового класса. Путаница в приведенных выше фрагментах возникает из-за того, что мы думаем об этих взаимосвязях (issubclass и isinstance) в терминах классов Python. Связь между object и type не может быть воспроизведена в чистом python.
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Проблема с куриным яйцом (ч.3)
Чтобы быть более точным, следующие взаимосвязи не могут быть воспроизведены в чистом Python:
Класс A является экземпляром класса B, а класс B является экземпляром класса A.
Класс A является экземпляром самого себя.
Эти отношения между object и type (оба являются экземплярами друг друга, а также самих себя)
Канал в Max🇷🇺
#theory // Just Python
Чтобы быть более точным, следующие взаимосвязи не могут быть воспроизведены в чистом Python:
Класс A является экземпляром класса B, а класс B является экземпляром класса A.
Класс A является экземпляром самого себя.
Эти отношения между object и type (оба являются экземплярами друг друга, а также самих себя)
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Отношения подклассов
Отношения подклассов не обязательно являются транзитивными в Python. Любому разрешено определять свой собственный, произвольный subclasscheck в метаклассе.
Когда issubclass(cls, Hashable) вызывается, он просто ищет не ложный "hash" метод в cls или что-либо, от чего он наследуется.
Поскольку object является хешируемым, но list не является хешируемым, это нарушает отношение транзитивности.
Канал в Max🇷🇺
#theory // Just Python
Отношения подклассов не обязательно являются транзитивными в Python. Любому разрешено определять свой собственный, произвольный subclasscheck в метаклассе.
Когда issubclass(cls, Hashable) вызывается, он просто ищет не ложный "hash" метод в cls или что-либо, от чего он наследуется.
Поскольку object является хешируемым, но list не является хешируемым, это нарушает отношение транзитивности.
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Равенство методов и идентичность (ч.1)
Функции - это дескрипторы. Всякий раз, когда к функции обращаются как к атрибуту, вызывается дескриптор, создающий объект метода, который "связывает" функцию с объектом, владеющим атрибутом. При вызове метод вызывает функцию, неявно передавая связанный объект в качестве первого аргумента (именно так мы получаем self в качестве первого аргумента, несмотря на то, что не передаем его явно).
Канал в Max🇷🇺
#theory // Just Python
Функции - это дескрипторы. Всякий раз, когда к функции обращаются как к атрибуту, вызывается дескриптор, создающий объект метода, который "связывает" функцию с объектом, владеющим атрибутом. При вызове метод вызывает функцию, неявно передавая связанный объект в качестве первого аргумента (именно так мы получаем self в качестве первого аргумента, несмотря на то, что не передаем его явно).
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Равенство методов и идентичность (ч.2)
Обращаясь classm дважды, мы получаем одинаковый объект, но не тот же? Давайте посмотрим, что происходит с экземплярами SomeClass
Обращение к classm or method дважды создает одинаковые, но не одинаковые объекты для одного и того же экземпляра SomeClass.
Канал в Max🇷🇺
#theory // Just Python
Обращаясь classm дважды, мы получаем одинаковый объект, но не тот же? Давайте посмотрим, что происходит с экземплярами SomeClass
Обращение к classm or method дважды создает одинаковые, но не одинаковые объекты для одного и того же экземпляра SomeClass.
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Методы: classmethod (ч.1)
Обращение к атрибуту несколько раз каждый раз создает объект метода! Поэтому o1.method is o1.method никогда не бывает правдивым. Доступ к функциям как атрибутам класса (в отличие от экземпляра), однако, не создает методы; так SomeClass.method is SomeClass.method и есть на самом деле.
Канал в Max🇷🇺
#theory // Just Python
Обращение к атрибуту несколько раз каждый раз создает объект метода! Поэтому o1.method is o1.method никогда не бывает правдивым. Доступ к функциям как атрибутам класса (в отличие от экземпляра), однако, не создает методы; так SomeClass.method is SomeClass.method и есть на самом деле.
Канал в Max
#theory // Just Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Методы: classm (ч.2)
Объект метода сравнивается равным, когда обе функции равны, а связанные объекты одинаковы. Так o1.method == o1.method это правдиво, хотя и не тот же объект в памяти.
staticmethod преобразует функции в дескриптор "no-op", который возвращает функцию как есть. Объекты метода никогда не создаются, поэтому сравнение с is является правдивым.
#theory // Just Python & Max
Объект метода сравнивается равным, когда обе функции равны, а связанные объекты одинаковы. Так o1.method == o1.method это правдиво, хотя и не тот же объект в памяти.
staticmethod преобразует функции в дескриптор "no-op", который возвращает функцию как есть. Объекты метода никогда не создаются, поэтому сравнение с is является правдивым.
#theory // Just Python & Max
Методы: staticm
Необходимость создавать новые объекты "метода" каждый раз, когда Python вызывает методы экземпляра, и необходимость каждый раз изменять аргументы для вставки self сильно повлияла на производительность. CPython 3.7 решил это, введя новые коды операций, которые имеют дело с вызывающими методами без создания объектов временных методов. Это используется только тогда, когда фактически вызывается доступная функция, поэтому фрагменты здесь не затрагиваются и по-прежнему генерируют методы :)
#theory // Just Python & Max
Необходимость создавать новые объекты "метода" каждый раз, когда Python вызывает методы экземпляра, и необходимость каждый раз изменять аргументы для вставки self сильно повлияла на производительность. CPython 3.7 решил это, введя новые коды операций, которые имеют дело с вызывающими методами без создания объектов временных методов. Это используется только тогда, когда фактически вызывается доступная функция, поэтому фрагменты здесь не затрагиваются и по-прежнему генерируют методы :)
#theory // Just Python & Max
Абсолютная правда
Реализация all функции эквивалентна.
all([]) возвращает True, поскольку итерируемый элемент пуст.
all([[]]) возвращает, False потому что переданный массив содержит один элемент, [] а в python пустой список является ложным.
all([[[]]]) и более высокие рекурсивные варианты всегда есть True. Это потому, что единственный элемент переданного массива ([[...]]) больше не является пустым, а списки со значениями соответствуют действительности.
#theory // Just Python & Max
Реализация all функции эквивалентна.
all([]) возвращает True, поскольку итерируемый элемент пуст.
all([[]]) возвращает, False потому что переданный массив содержит один элемент, [] а в python пустой список является ложным.
all([[[]]]) и более высокие рекурсивные варианты всегда есть True. Это потому, что единственный элемент переданного массива ([[...]]) больше не является пустым, а списки со значениями соответствуют действительности.
#theory // Just Python & Max
Удивительная запятая
Запятая в конце не всегда допустима в списке формальных параметров функции Python.
В Python список аргументов определяется частично с помощью начальных и частично завершающих запятых. Этот конфликт приводит к ситуациям, когда запятая оказывается запертой посередине, и ни одно правило ее не принимает.
Примечание: Проблема с запятыми в конце исправлена в Python 3.6. Замечания в этом посте кратко обсуждают различные варианты использования запятых в конце в Python.
#theory // Just Python & Max
Запятая в конце не всегда допустима в списке формальных параметров функции Python.
В Python список аргументов определяется частично с помощью начальных и частично завершающих запятых. Этот конфликт приводит к ситуациям, когда запятая оказывается запертой посередине, и ни одно правило ее не принимает.
Примечание: Проблема с запятыми в конце исправлена в Python 3.6. Замечания в этом посте кратко обсуждают различные варианты использования запятых в конце в Python.
#theory // Just Python & Max
Строки и обратная косая черта (ч.1)
В обычной строке python обратная косая черта используется для экранирования символов, которые могут иметь особое значение (например, одинарная кавычка, двойная кавычка и сама обратная косая черта).
#theory // Just Python & Max
В обычной строке python обратная косая черта используется для экранирования символов, которые могут иметь особое значение (например, одинарная кавычка, двойная кавычка и сама обратная косая черта).
#theory // Just Python & Max
Строки и обратная косая черта (ч.2)
В необработанном строковом литерале (на что указывает префикс r) обратная косая черта передается как есть вместе с поведением экранирования следующего символа.
Это означает, что когда анализатор обнаруживает обратную косую черту в необработанной строке, он ожидает, что за ней последует другой символ. И в нашем случае (print(r"\")) обратная косая черта экранировала завершающую кавычку, оставляя анализатор без завершающей кавычки (отсюда SyntaxError). Вот почему обратная косая черта не работает в конце необработанной строки.
#theory // Just Python & Max
В необработанном строковом литерале (на что указывает префикс r) обратная косая черта передается как есть вместе с поведением экранирования следующего символа.
Это означает, что когда анализатор обнаруживает обратную косую черту в необработанной строке, он ожидает, что за ней последует другой символ. И в нашем случае (print(r"\")) обратная косая черта экранировала завершающую кавычку, оставляя анализатор без завершающей кавычки (отсюда SyntaxError). Вот почему обратная косая черта не работает в конце необработанной строки.
#theory // Just Python & Max
Не узел!
Приоритет оператора влияет на то, как вычисляется выражение, и == operator имеет более высокий приоритет, чем not operator в Python.
Таким образом, not x == y эквивалентноnot (x == y), что эквивалентно not (True == False) окончательной оценке True.
Но x == not y вызывает SyntaxError вопрос, потому что его можно считать эквивалентным, (x == not) y а не x == (not y) тем, что вы могли ожидать на первый взгляд.
Анализатор ожидал, что not токен будет частью not in оператора (потому что оба оператора == и not in имеют одинаковый приоритет), но после того, как не смог найти in токен, следующий за not токеном, он выдает SyntaxError.
#theory // Just Python & Max
Приоритет оператора влияет на то, как вычисляется выражение, и == operator имеет более высокий приоритет, чем not operator в Python.
Таким образом, not x == y эквивалентноnot (x == y), что эквивалентно not (True == False) окончательной оценке True.
Но x == not y вызывает SyntaxError вопрос, потому что его можно считать эквивалентным, (x == not) y а не x == (not y) тем, что вы могли ожидать на первый взгляд.
Анализатор ожидал, что not токен будет частью not in оператора (потому что оба оператора == и not in имеют одинаковый приоритет), но после того, как не смог найти in токен, следующий за not токеном, он выдает SyntaxError.
#theory // Just Python & Max
Половина строк в тройных кавычках
Python поддерживает неявную конкатенацию строковых литералов.
''' и """ также являются разделителями строк в Python, которые вызывают ошибку SyntaxError, потому что интерпретатор Python ожидал, что в качестве разделителя будет заключена тройная кавычка при сканировании текущего строкового литерала в тройных кавычках.
#theory // Just Python & Max
Python поддерживает неявную конкатенацию строковых литералов.
''' и """ также являются разделителями строк в Python, которые вызывают ошибку SyntaxError, потому что интерпретатор Python ожидал, что в качестве разделителя будет заключена тройная кавычка при сканировании текущего строкового литерала в тройных кавычках.
#theory // Just Python & Max
Что не так с логическими значениями? (ч.1)
Изначально в Python не было bool типа (люди использовали 0 для false и ненулевое значение, такое как 1 для true). True, False и bool тип был добавлен в версиях 2.x, но для обратной совместимости True и False нельзя было сделать константами. Они просто были встроенными переменными, и их можно было переназначить.
#theory // Just Python & Max
Изначально в Python не было bool типа (люди использовали 0 для false и ненулевое значение, такое как 1 для true). True, False и bool тип был добавлен в версиях 2.x, но для обратной совместимости True и False нельзя было сделать константами. Они просто были встроенными переменными, и их можно было переназначить.
#theory // Just Python & Max
Что не так с логическими значениями? (ч.2)
bool является подклассом int в Python. И, таким образом, True и False являются экземплярами int. Целочисленное значение True равно 1, а значение из False равно 0.
#theory // Just Python & Max
bool является подклассом int в Python. И, таким образом, True и False являются экземплярами int. Целочисленное значение True равно 1, а значение из False равно 0.
#theory // Just Python & Max
Что не так с логическими значениями? (ч.3)
Python 3 был обратно несовместим, проблема была наконец исправлена, и, таким образом, последний фрагмент не будет работать с Python 3.x!
#theory // Just Python & Max
Python 3 был обратно несовместим, проблема была наконец исправлена, и, таким образом, последний фрагмент не будет работать с Python 3.x!
#theory // Just Python & Max
Атрибуты класса и атрибуты экземпляра (ч.1)
Переменные класса и переменные в экземплярах класса внутренне обрабатываются как словари объекта класса. Если имя переменной не найдено в словаре текущего класса, выполняется поиск по нему в родительских классах.
#theory // Just Python & Max
Переменные класса и переменные в экземплярах класса внутренне обрабатываются как словари объекта класса. Если имя переменной не найдено в словаре текущего класса, выполняется поиск по нему в родительских классах.
#theory // Just Python & Max
Атрибуты класса и атрибуты экземпляра (ч.2)
+= Оператор изменяет изменяемый объект на месте, не создавая новый объект. Таким образом, изменение атрибута одного экземпляра влияет на другие экземпляры, а также на атрибут class.
#theory // Just Python & Max
+= Оператор изменяет изменяемый объект на месте, не создавая новый объект. Таким образом, изменение атрибута одного экземпляра влияет на другие экземпляры, а также на атрибут class.
#theory // Just Python & Max