Перейти к содержимому

Builtins python что это

  • автор:

Builtins python что это

Встроенные функции Python содержатся в модуле __ builtin __(импортировать его для использования функций не нужно):

[‘ArithmeticError’, ‘AssertionError’, ‘AttributeError’,

‘DeprecationWarning’, ‘EOFError’, ‘Ellipsis’, ‘EnvironmentError’,

‘Exception’, ‘FloatingPointError’, ‘IOError’, ‘ImportError’,

‘IndentationError’, ‘IndexError’, ‘KeyError’, ‘KeyboardInterrupt’,

‘LookupError’, ‘MemoryError’, ‘NameError’, ‘None’, ‘NotImplemented’,

‘NotImplementedError’, ‘OSError’, ‘OverflowError’, ‘OverflowWarning’,

‘ReferenceError’, ‘RuntimeError’, ‘RuntimeWarning’, ‘StandardError’,

‘StopIteration’, ‘SyntaxError’, ‘SyntaxWarning’, ‘SystemError’,

‘SystemExit’, ‘TabError’, ‘TypeError’, ‘UnboundLocalError’,

‘UnicodeError’, ‘UserWarning’, ‘ValueError’, ‘Warning’,

‘ZeroDivisionError’, ‘_’, ‘__debug__’, ‘__doc__’, ‘__import__’,

‘__name__’, ‘abs’, ‘apply’, ‘buffer’, ‘callable’, ‘chr’, ‘classmethod’,

‘cmp’, ‘coerce’, ‘compile’, ‘complex’, ‘copyright’, ‘credits’, ‘delattr’,

‘dict’, ‘dir’, ‘divmod’, ‘eval’, ‘execfile’, ‘exit’, ‘file’, ‘filter’,

‘float’, ‘getattr’, ‘globals’, ‘hasattr’, ‘hash’, ‘help’, ‘hex’, ‘id’,

‘input’, ‘int’, ‘intern’, ‘isinstance’, ‘issubclass’, ‘iter’, ‘len’,

‘license’, ‘list’, ‘locals’, ‘long’, ‘map’, ‘max’, ‘min’, ‘object’,

‘oct’, ‘open’, ‘ord’, ‘pow’, ‘property’, ‘quit’, ‘range’, ‘raw_input’,

‘reduce’, ‘reload’, ‘repr’, ’round’, ‘setattr’, ‘slice’, ‘staticmethod’,

‘str’, ‘super’, ‘tuple’, ‘type’, ‘unichr’, ‘unicode’, ‘vars’, ‘xrange’,

Доступ к встроенным идентификаторам (функциям и константам) Python

Модуль builtins обеспечивает прямой доступ ко всем встроенным идентификаторам Python. Это значит, что например полное название функции open() выглядит на самом деле как builtins.open() .

Документацию по встроенным функциям и константам смотрите в разделах «Встроенные функции языка Python» и «Встроенные константы языка Python».

Этот модуль обычно не доступен явно в большинстве приложений, но может быть полезен в модулях, которые предоставляют объекты с тем же именем, что и встроенное значение. Например в модуле, который хочет реализовать свою функцию open() , которая оборачивает встроенную функцию open() , то этот модуль можно использовать напрямую.

import builtins def open(path): f = builtins.open(path, 'r') return UpperCaser(f) class UpperCaser: '''Wrapper around a file that converts output to upper-case.''' def __init__(self, f): self._f = f def read(self, count=-1): return self._f.read(count).upper() # . 

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

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

Python 3.8+

Когда выходит очередная версия Python, все внимание достается новым фичам языка: моржовому оператору, слиянию словарей, паттерн-матчингу. Еще много пишут об изменениях в асинхронной работе (модуль asyncio ) и типизации (модуль typing ) — эти модули на виду и бурно развиваются.

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

Конечно, это не исчерпывающий список. Пишу только о тех изменениях, которые заинтересовали лично меня. Но поскольку я не слишком сильно отличаюсь от «среднего» бэкенд-разработчика на питоне — вполне вероятно, что вас они тоже заинтересуют. Если что-то пропустил — дополняйте в комментариях.

Модули идут в алфавитном порядке, так что если заскучаете на первых (малоизвестных) представителях, не унывайте — дальше будет интереснее.

Все примеры рабочие. Выполнять можно в песочнице (ссылки под примерами), либо локально. Если локально у вас старый Python — запускайте через Docker:

$ docker run -it --rm python:3.10-alpine

array

Модуль array предоставляет компактные однотипные числовые массивы. Используется намного реже, чем знаменитый собрат list .

Метод array.index() находит значение в массиве и возвращает индекс найденного элемента. Теперь он поддерживает необязательные параметры start и stop , которые задают интервал поиска (3.10+):

from array import array arr = array("i", [7, 11, 19, 42]) idx = arr.index(11) # idx == 1 idx = arr.index(11, 2) # ValueError: array.index(x): x not in array

base64

Модуль base64 кодирует бинарные данные в ASCII-строки по алгоритмам Base16, Base32 и Base64.

Он обзавелся парой новых функций b32hexencode() и b32hexdecode() , которые используют расширенный 32-символьный алфавит согласно RFC 4648 (3.10+):

import base64 bytes = b"python is awesome" base64.b32encode(bytes) # b'OB4XI2DPNYQGS4ZAMF3WK43PNVSQ====' base64.b32hexencode(bytes) # b'E1SN8Q3FDOG6ISP0C5RMASRFDLIG===='

bisect

Модуль bisect работает с отсортированными списками методом бинарного поиска. Основные функции:

  • bisect() находит элемент в списке;
  • insort() добавляет элемент, сохраняя порядок.
import bisect lst = [7, 11, 19, 42] idx = bisect.bisect(lst, 12) # idx == 2 bisect.insort(lst, 12) # [7, 11, 12, 19, 42]

С версии 3.10 все функции модуля поддерживают необязательный параметр key . Это функция, которая возвращает значение элемента списка. Удобно использовать, если элементы напрямую несравнимы:

import bisect import operator p1 = p2 = p3 = key = operator.itemgetter("name") people = sorted([p1, p2, p3], key=key) # Bob, Diane, Emma idx = bisect.bisect(people, "Dan") # TypeError: '

builtins

Модуль builtins содержит все «встроенные» функции и классы, которые программисты используют без всяких импортов: int , list , len() , open() и тому подобное.

import builtins list is builtins.list # True len is builtins.len # True

У строки появились методы str.removeprefix() и str.removesuffix() , которые отрезают голову и хвост соответственно (3.9+):

s = "Python is awesome" s.removeprefix("Python is ") # 'awesome' s.removesuffix(" is awesome") # 'Python'

У целого числа добавился метод int.bit_count() , который возвращает количество единиц в бинарном представлении числа (3.10+):

n = 42 bin(n) # '0b101010' n.bit_count() # 3

Методы словаря dict.keys() , dict.values() и dict.items() возвращают объекты-представления (view objects), которые не дублируют данные словаря, а ссылаются на них. Раньше из этих объектов нельзя было получить обратную ссылку на словарь, а теперь можно — через атрибут .mapping (3.10+):

people = < "Diane": 70, "Bob": 78, "Emma": 84 >keys = people.keys() # dict_keys(['Diane', 'Bob', 'Emma']) keys.mapping["Bob"] # 78

Функция объединения коллекций zip() получила параметр strict . Он проверяет, что последовательности одинаковой длины (3.10+):

keys = ["Diane", "Bob", "Emma"] vals = [70, 78, 84, 42] pairs = zip(keys, vals) list(pairs) # [('Diane', 70), ('Bob', 78), ('Emma', 84)] pairs = zip(keys, vals, strict=True) list(pairs) # ValueError: zip() argument 2 is longer than argument 1

dataclasses

Модуль dataclasses генерит классы по спецификации.

Датаклассы теперь могут использовать слоты (slots) для компактных объектов с фиксированным набором свойств (3.10+).

from dataclasses import dataclass @dataclass class Person: id: int name: str diane = Person(id=11, name="Diane") diane.__dict__ # diane.salary = 70 # ok
from dataclasses import dataclass @dataclass(slots=True) class SlotPerson: id: int name: str bob = SlotPerson(id=12, name="Bob") bob.__dict__ # AttributeError: 'SlotPerson' object has no attribute '__dict__' bob.__slots__ # ('id', 'name') bob.salary = 78 # AttributeError: 'SlotPerson' object has no attribute 'salary'

Кроме того, датакласс теперь можно заставить принимать только словарные (keyword-only) параметры при создании объекта (3.10+):

from dataclasses import dataclass @dataclass(kw_only=True) class KeywordPerson: id: int name: str diane = KeywordPerson(id=11, name="Diane") # ok diane = KeywordPerson(11, "Diane") # TypeError: KeywordPerson.__init__() takes 1 positional argument but 3 were given

datetime

Модуль datetime работает с датой и временем.

Добавились конструкторы date.fromisocalendar() и datetime.fromisocalendar() , которые создают дату из троицы (год, неделя, день_недели) (3.8+):

import datetime as dt day = dt.date(2022, 9, 13) day.isocalendar() # datetime.IsoCalendarDate(year=2022, week=37, weekday=2) year, week, day = day.isocalendar() next_day = dt.date.fromisocalendar(year, week, day+1) # datetime.date(2022, 9, 14)

Кроме того, метод .isocalendar() теперь возвращает не обычный кортеж, а именованный IsoCalendarDate (3.9+). Это видно в примере выше.

fractions

Модуль fractions работает с рациональными числами.

Он получил метод Fraction.as_integer_ratio() и научился возвращать дробь как пару (числитель, знаменатель) , тем самым исправив вековой позор обычного float (3.8+):

(0.25).as_integer_ratio() # (1, 4) (0.5).as_integer_ratio() # (1, 2) (0.2).as_integer_ratio() # (3602879701896397, 18014398509481984) # oopsie
from fractions import Fraction Fraction("0.2").as_integer_ratio() # (1, 5) # so much better

Справедливости ради, decimal.Decimal научился так делать еще в 3.6. Но все равно приятно.

functools

Модуль functools — сборник вспомогательных функций высшего порядка. Одна из них — lru_cache() , которая кеширует дорогие вычисления:

import functools import time @functools.lru_cache(maxsize=256) def find_user(name): # imitating slow search time.sleep(1) user = return user find_user("Diane") # kinda slow find_user("Diane") # blazingly fast

Раньше у нее всегда нужно было указывать размер кеша. А теперь можно указать @lru_cache без аргументов, и будет использоваться умолчательный размер 128 (3.8+).

Кроме того, можно узнать параметры кеша (3.9+):

find_user.cache_parameters() #

Если памяти вам не жалко, вместо @lru_cache можно использовать @cache — он безразмерный (3.9+).

Новый декоратор @cached_property кеширует вычисляемое свойство объекта (3.8+):

import functools import statistics class Dataset: def __init__(self, seq): self._data = tuple(seq) @functools.cached_property def stdev(self): return statistics.stdev(self._data) dataset = Dataset(range(1_000_000)) dataset.stdev # kinda slow dataset.stdev # blazingly fast

А @singledispatchmethod перегружает работу метода в зависимости от типа параметра (3.8+):

import functools class Divider: @functools.singledispatchmethod def divide(self, dividend, divisor): raise NotImplementedError("Do not know how to divide those") @divide.register def _(self, dividend: int, divisor: int): return dividend // divisor @divide.register def _(self, dividend: str, divisor: int): # this is really stupid, I know newlen = len(dividend) // divisor return dividend[:newlen] divider = Divider() divider.divide(10, 2) # 5 divider.divide("hello world", 2) # 'hello'

Чувствуете, джавой потянуло?

glob

Модуль glob находит файлы и каталоги, подходящие под шаблон.

Теперь благодаря параметру root_dir в glob() и iglob() можно указать корневую директорию поиска (3.10+):

import glob import os os.getcwd() # '/' glob.glob("*", root_dir="/usr") # ['local', 'share', 'bin', 'lib', 'sbin', 'src']

Пустячок, а приятно.

graphlib

Модуль graphlib работает с графами. И знаете что? Это абсолютно новый модуль! (3.9+)

Пока у него только одна возможность — топологическая сортировка графов (такой порядок вершин, что для любых u → v , вершина u идет перед v ):

from graphlib import TopologicalSorter graph = , "Cindy": , "Bob": > # Alice → Bob → Diane # ↳ Cindy ↗ sorter = TopologicalSorter(graph) list(sorter.static_order()) # ['Alice', 'Cindy', 'Bob', 'Diane']

itertools

Модуль itertools предоставляет разнообразные итераторы для эффективной работы с коллекциями (эффективной с точки зрения использования памяти).

Одна из функций — accumulate() — рассчитывает скользящий агрегат. Теперь у нее появился параметр initial , который задает начальное значение (3.8+):

import itertools seq = [7, 11, 19, 42] accumulator = itertools.accumulate(seq) list(accumulator) # [7, 18, 37, 79] accumulator = itertools.accumulate(seq, initial=100) list(accumulator) # [100, 107, 118, 137, 179]

А новая замечательная функция pairwise() проходит по коллекции и возвращает пары последовательных элементов (3.10+):

import itertools seq = [7, 11, 19, 42] pairer = itertools.pairwise(seq) list(pairer) # [(7, 11), (11, 19), (19, 42)]

math

Модуль math включает вагон и маленькую тележку математических функций.

Тут много нового:

  • dist() считает евклидово расстояние между точками (3.8+);
  • perm() и comb() считают перестановки и сочетания (3.8+);
  • lcm() находит наименьшее общее кратное (3.9+);
  • gcd() теперь считает наибольший общий делитель для произвольного количества аргументов (3.9+).
import math math.dist((1,1), (4, 5)) # 5.0 math.perm(5, 2) # 20 math.comb(5, 2) # 10 math.lcm(9, 27, 60) # 540 math.gcd(9, 27, 60) # 3

А prod() перемножает элементы последовательности (3.8+):

import math seq = range(3, 9) math.prod(seq) # 20160

random

Модуль random работает со случайными числами.

Новый метод randbytes() генерит случайную байтовую строку (3.9+):

import random random.randbytes(4) # b'\x8b\xd4\x8f\xc9'

shlex

Модуль shlex бьет строку на токены по правилам командной строки Unix.

А теперь не только бьет, но и обратно объединяет — благодаря функции join() (3.8+):

import shlex tokens = ["echo", "-n", "Python is awesome"] shlex.join(tokens) # "echo -n 'Python is awesome'"

shutil

Модуль shutil работает с файлами и каталогами: копирует, переносит, удаляет.

И копировать каталоги теперь стало немного удобнее — благодаря параметру dirs_exist_ok в функции copytree() (3.8+). С ним функция не сломается, даже если целевой каталог уже существует:

from pathlib import Path import shutil tmp = Path("/tmp") src = tmp.joinpath("src") src.mkdir() src.joinpath("src.txt").touch() # /tmp/src # /tmp/src/src.txt dst = tmp.joinpath("dst") dst.mkdir() # /tmp/dst shutil.copytree(src, dst) # FileExistsError: [Errno 17] File exists: '/tmp/dst' shutil.copytree(src, dst, dirs_exist_ok=True) # PosixPath('/tmp/dst')

statistics

Модуль statistics работает с математической статистикой. Как и math , он заметно развился в последних версиях. Это еще не scipy , но уже и не тот детский сад, что был в 3.4.

  • fmean() считает среднее арифметическое как mean() , только быстрее (3.8+);
  • geometric_mean() считает геометрическое среднее (3.8+);
  • multimode() возвращает моды (самые частые значения в датасете), даже если их несколько (в отличие от mode() ) (3.8+);
  • quantiles() разбивает датасет на квантили (3.8+).
import statistics seq = list(range(1, 10)) statistics.fmean(seq) # 5.0 statistics.geometric_mean(seq) # 4.147166274396913 statistics.multimode(seq) # [1, 2, 3, 4, 5, 6, 7, 8, 9] statistics.multimode("python is awesome") # ['o', ' ', 's', 'e'] statistics.quantiles(seq) # [2.5, 5.0, 7.5]

NormalDist описывает нормальное распределение случайной величины (3.8+):

from statistics import NormalDist birth_weights = NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]) drug_effects = NormalDist(0.4, 0.15) combined = birth_weights + drug_effects round(combined.mean, 1) # 3.1 round(combined.stdev, 1) # 0.5

Появились корреляция Пирсона correlation() и ковариация covariance() (3.10+):

import statistics x = [1, 2, 3, 4, 5, 6, 7, 8, 9] y = [9, 8, 7, 6, 5, 4, 3, 2, 1] statistics.correlation(x, x) # 1.0 statistics.correlation(x, y) # -1.0 statistics.covariance(x, x) # 7.5 statistics.covariance(x, y) # -7.5

И даже линейная регрессия linear_regression() (3.10+):

import statistics movies_by_year = < 2000: 371, 2003: 507, 2006: 608, 2009: 520, 2012: 669, 2015: 708, 2018: 873, 2021: 403, >x = movies_by_year.keys() y = movies_by_year.values() slope, intercept = statistics.linear_regression(x, y) year_2022 = round(slope * 2022 + intercept) # 697

Кстати, модуль statistics славится еще и шикарной документацией. Рекомендую.

zoneinfo

Модуль zoneinfo предоставляет информацию о часовых поясах по всему миру. Еще один новый модуль! (3.9+)

До появления zoneinfo питон щеголял единственным часовым поясом timezone.utc , удивляя разработчиков из других языков. Теперь это исправили:

import datetime as dt from zoneinfo import ZoneInfo utc = dt.datetime(2022, 9, 13, hour=21, tzinfo=dt.timezone.utc) # 2022-09-13 21:00:00+00:00 paris = utc.astimezone(ZoneInfo("Europe/Paris")) # 2022-09-13 23:00:00+02:00 tokyo = utc.astimezone(ZoneInfo("Asia/Tokyo")) # 2022-09-14 06:00:00+09:00 sydney = utc.astimezone(ZoneInfo("Australia/Sydney")) # 2022-09-14 07:00:00+10:00

Итого

Мы рассмотрели аж 17 модулей от 27 разработчиков — и это без учета asyncio , typing и великого множества прочих, более низкоуровневых. Как видите, стандартная библиотека активно развивается. И фичи, на мой взгляд, добавляют весьма разумно. Буду рад, если что-то из новшеств пригодится вам в работе!

А если хотите узнать больше о стандартной библиотеке Python — подписывайтесь на мой канал @ohmypy

Обязательно ли импортировать builtins?

Согласно правилу LEGB переменная сначала ищется в локальной области видимости, затем в замыкании, затем в глобальной области видимости, затем во встроенной области видимости. Встроенная область видимости это обычный модуль, он называется builtins. Как пишут в учебниках по python3, чтобы им воспользоваться, его нужно просто импортировать.

Я посмотрел его содержимое так:

>>> import builtins >>> dir(builtins) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

Как видите, в нём есть например функция type.

Далее я закрыл сеанс работы с интерактивной оболочкой и открыл новый. При этом, как понимаете модуль builtins не импортировался. Далее я попытался использовать функцию type так:

kalinin@lenovo ~/python/hello $ python3 Python 3.5.2 (default, Nov 12 2018, 13:43:14) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> dir(builtins) Traceback (most recent call last): File "", line 1, in NameError: name 'builtins' is not defined >>> type(1)

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

  • Вопрос задан более трёх лет назад
  • 200 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *