Я обнаружил странное явление: некоторые методы в стандартной библиотеке Python можно вызывать как функции.
Например, есть метод randint(), определенный в классе Random в модуле random.py.
Насколько я понимаю, когда мы хотим его вызвать, мы должны сначала импортировать модуль random, а затем объявить экземпляр класса Random, чтобы метод randint() можно было вызвать, например
import random as rd
aaa = rd.Random()
aaa.randint()
Но я только что обнаружил, что randint() можно вызвать как функцию и нет необходимости делать, как указано выше:
import random as rd
rd.randint()
Вот мне и интересно, как происходит это нелогичное явление?
Почему методы в стандартной библиотеке Python можно вызывать как функции?






Заглянув в random.py, мы видим, что фактически создается экземпляр, а его методы экспортируются как функции уровня модуля. В этом нет ничего волшебного.
Комментарий там прекрасно это описывает:
# Create one instance, seeded from current time, and export its methods
# as module-level functions. The functions share state across all uses
# (both in the user's code and in the Python libraries), but that's fine
# for most programs and is easier for the casual user than making them
# instantiate their own Random() instance.
_inst = Random()
# .. SNIP ..
randint = _inst.randint
Другие модули стандартной библиотеки используют другой, но похожий подход к экспорту функций уровня модуля. Например. модуль re использует внутреннюю функцию _compile() для создания локального экземпляра Pattern и позволяет ему выполнять всю работу (строка документации опущена для краткости):
def search(pattern, string, flags=0):
return _compile(pattern, flags).search(string)
Мы можем заключить, что не существует общего механизма для повышения уровня методов до функций уровня модуля. Это просто удачный дизайн интерфейса со стороны отдельных модулей.
Привет, Фридрих! Большое вам спасибо, ваш ответ действительно имеет смысл!