Если вы выйдете из интерпретатора Python и введете его снова, написанный вами код будет потерян. Поэтому, если вы хотите написать более длинную программу, вам лучше использовать текстовый редактор(IDE)
Для поддержки этого в Python есть способ поместить код в файл и использовать его как скрипт или запускать интерактивно в интерпретаторе. Такой файл называется модулем. Модули могут быть импортированы в другие модули или в основной модуль (набор переменных, к которым у вас есть доступ в скрипте).
Модуль - это файл, содержащий определения и операторы Python. Имя файла - это имя модуля с .py добавленным суффиксом . Внутри модуля имя модуля (в виде строки) доступно в качестве значения глобальной переменной __name__. Например, используйте ваш любимый текстовый редактор, чтобы создать файл с именем fibo.py в текущем каталоге со следующим содержимым:
# Модуль чисел Фибоначчи
def fib(n): # написать ряд Фибоначчи до n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # вывести ряд Фибоначчи до n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
Теперь импортируйте этот модель в интрпретаторе python командой:
>>> import fibo
И словите ошибку.
Суть в том, что интерпетатор берет модули из определенных путей. Чтобы уведеть откуда введите:
>>> import sys
>>> sys.path
Вам высветится список с путями, откуда берутся модули. И чтобы добавить туда наш модуль используйте следующий код:
>>> import sys
>>> sys.path.append("path/to/file")
И теперь вы сможеет импортировать ваш файл:
>>> import fibo
Этот код ничего не выводит. Он просто добавляет этот модуль к нашему скрипту. Но используя имя модуля и имена функций, переменных мы можем получить доступ к функционалу модуля:
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Если вы собираетесь использовать функцию часто, вы можете назначить ее локальному имени:
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Больше о модулях
Модуль может содержать исполняемые операторы, а также функции. Эти операторы предназначены для инициализации модуля. Они выполняются только в первый раз, когда имя модуля встречается в импорте. (Они также запускаются, если файл выполняется как скрипт.)
Каждый модуль имеет свою собственную таблицу частных символов, которая используется в качестве глобальной таблицы символов всеми функциями, определенными в модуле. Таким образом, автор модуля может использовать глобальные переменные в модуле, не беспокоясь о случайных столкновениях с глобальными переменными пользователя. С другой стороны, если вы знаете, что делаете, вы можете прикоснуться к глобальным переменным модуля, используя те же обозначения, что и для ссылок на его функции.
Модули могут импортировать другие модули. Обычно, но не обязательно помещать все import операторы в начале кода.
Существует вариант import оператора, который импортирует имена из модуля. Например:
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Существует даже вариант для импорта всех имен, определенных модулем:
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Это импортирует все имена, кроме тех, которые начинаются с подчеркивания ( _). В большинстве случаев программисты Python не используют эту возможность, поскольку она вводит неизвестный набор имен в интерпретатор, возможно, скрывая некоторые вещи, которые вы уже определили.
Обратите внимание, что в целом практика импорта *из модуля или пакета не одобряется, так как это часто вызывает плохо читаемый код. Тем не менее, можно использовать его для сохранения набора текста в интерактивных сеансах.
Оператор as позволяет дать другое имя модулю или подмодулю. Обычно это используется, когда име подуля слишком большое:
# импортируем модуль fibo, как fib
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
# импортируем функцию fib, как fibonacci
>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
По соображениям эффективности каждый модуль импортируется только один раз за сеанс интерпретатора. Поэтому, если вы меняете свои модули, вы должны перезапустить интерпретатор - или, если это только один модуль, который вы хотите протестировать в интерактивном режиме, используйте:
>>> import sys
>>> import importlib
>>> importlib.reload(sys)
Выполнение модулей в качестве скриптов
Когда вы запускаете модуль Python через терминалл
python fibo.py <arguments>
В таком случае модуль будет запущен не как модуль, а как полноценный скрипт. И значение __name__ будет установлено в __main__. Поэтому мы можем использовать это, например:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34
Если модуль импортирован, код не запускается:
>>> import fibo
>>>
Потому что в данном случае __name__ будет равно названию модуля.
>>> import fibo
>>> fibo.__name__
'fibo'
Поиск модуля
Когда импортируется модуль Python сначал ищет встроенный модуль с таким именем, а потом уже ищет созданный модуль в списке sys.path.
И чтобы добавить наш путь в path используйте sys.path.append(path/to/file)
"Скомпилированные" python файлы
Чтобы ускорить загрузку модулей, Python кэширует скомпилированную версию каждого модуля в каталог __pycache__.Обычно он содержит номер версии Python. Например, в выпуске CPython 3.3 скомпилированная версия модуля spam.py будет кэшироваться как module.version.pyc__pycache__/spam.cpython-33.pyc. Это соглашение об именах позволяет сосуществовать скомпилированным модулям из разных выпусков и разных версий Python.
Python проверяет дату модификации источника по скомпилированной версии, чтобы определить, устарела ли она и нуждается ли в перекомпиляции.
Стандартные модули
Python поставляется с библиотекой стандартных модулей. Некоторые модули встроены в интерпретатор; они обеспечивают доступ к операциям, которые не являются частью языка, но, тем не менее, встроены либо для эффективности, либо для обеспечения доступа к примитивам операционной системы. Набор таких модулей является опцией конфигурации, которая также зависит от базовой платформы. Например, winreg модуль предоставляется только в системах Windows.
Но один конкретный модуль заслуживает некоторого внимания: sys он встроен в каждый интерпретатор Python. Например переменные sys.ps1и sys.ps2определяют строки, используемые в качестве первичных и вторичных приглашений:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>
Вот полный список встроенных модулей python https://docs.python.org/3/py-modindex.html
Функция dir()
Встроенная функция dir() используется, чтобы узнать, какие имена определяет модуль. Возвращает отсортированный список строк:
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
'__package__', '__stderr__', '__stdin__', '__stdout__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
'_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
'call_tracing', 'callstats', 'copyright', 'displayhook',
'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
'thread_info', 'version', 'version_info', 'warnoptions']
Без аргументов dir() перечисляет имена, которые вы определили в настоящее время:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
Обратите внимание, что в нем перечислены все типы имен: переменные, модули, функции и т. Д.
dir() не перечисляет имена встроенных функций и переменных. Если вы хотите список этих, они определены в стандартном модуле builtins:
>>> 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',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
'__debug__', '__doc__', '__import__', '__name__', '__package__', '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']
Пакеты
Пакеты - это структурированный набор модулей, которые вместе образуют многофункционально нечто.
Предположим, вы хотите создать набор модулей («пакет») для обработки звуковых файлов и звуковых данных. Есть много различных форматов звуковых файлов (обычно признаваемых их расширение, например: .wav, .aiff, .au), так что вам могут понадобиться создать и поддерживать растущую коллекцию модулей для преобразования между различными форматами файлов. Есть также много разных операций, которые вы можете выполнять над звуковыми данными (например, микширование, добавление эха, применение функции эквалайзера, создание искусственного стереоэффекта), поэтому, кроме того, вы будете писать нескончаемый поток модулей для выполнения. эти операции. Вот возможная структура вашего пакета (выраженная в терминах иерархической файловой системы):
sound/ Сам пакет
__init__.py Инициализация звуковой пакет
formats/ Подпакет для преобразования формата файла
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Подпакет для звуковых эффектов
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Подпакет для фильтров
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
Пользователи пакета могут импортировать отдельные модули из пакета, например:
import sound.effects.echo
Это загружает подмодуль sound.effects.echo. На него должно быть указано полное имя.
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
Альтернативный способ импорта подмодуля:
from sound.effects import echo
Это также загружает подмодуль echoи делает его доступным без префикса пакета, поэтому его можно использовать следующим образом:
echo.echofilter(input, output, delay=0.7, atten=4)
Еще один вариант - импортировать нужную функцию или переменную напрямую:
from sound.effects.echo import echofilter
Опять же, это загружает подмодуль echo, но это делает его функцию echofilter()напрямую доступной:
echofilter(, output, delay=0.7, atten=4)
Импорт * из пакета
Что происходит, когда пользователь пишет from sound.effects import *? В идеале можно надеяться, что это каким-то образом поступит в файловую систему, найдет, какие подмодули присутствуют в пакете, и импортирует их все. Это может занять много времени, и импорт субмодулей может иметь нежелательные побочные эффекты, которые должны происходить, только если субмодуль явно импортирован.
Единственное решение для автора пакета - предоставить явный индекс пакета. import Оператор использует следующее соглашение: если пакет в __init__.py коде определяет список с именем __all__, он берется список имен модулей , которые должны быть импортированы, когда встречаются from package import *. Автор пакета должен поддерживать этот список в актуальном состоянии после выпуска новой версии пакета. Авторы пакетов могут также принять решение не поддерживать его, если они не видят использования для импорта * из своего пакета. Например, sound/effects/__init__.py файл может содержать следующий код:
__all__ = ["echo", "surround", "reverse"]
Это будет означать, что в from sound.effects import *sound будут импортированы три именованных подмодуля пакета.
Внутрипакетные ссылки
Когда пакеты структурированы в подпакеты (как в примере с soundпакетом), вы можете использовать абсолютный импорт для ссылки на подмодули пакетов одного уровня. Например, если модуль sound.filters.vocoderдолжен использовать echoмодуль в sound.effectsпакете, он может использовать .from sound.effects import echo
Вы также можете написать относительный импорт в форме оператора импорта from module import name. В этих импортах используются начальные точки для обозначения текущих и родительских пакетов, участвующих в относительном импорте. Например, из модуля вы можете использовать: surround
from . import echo
from .. import formats
from ..filters import equalizer
Обратите внимание, что относительный импорт основан на имени текущего модуля. Поскольку имя основного модуля всегда "__main__", модули, предназначенные для использования в качестве основного модуля приложения Python, всегда должны использовать абсолютный импорт.
Пакеты в нескольких каталогах
Пакеты поддерживают еще один специальный атрибут __path__. Этот аттрибут хранит путь к пакету, а точнее туда, где находится файл __init__.py.
Заключение
Отлично. Скоро напишите свою библиотеку
Пост создан для тг-канала @coolcoders