Дикий Григорий

Full-stack веб-разработчик

Модули в Python

В Python существует понятие модулей - это набор ваших функций, переменных объеденных одним файлом с расширением .py. Удобство модулей заключается в том, что его можно импортировать в ваши программы, чтобы использовать функции модуля. Давайте посмотрим как использовать модули стандартной библиотеки Python:

import sys


print('Аргументы командной строки:')
for i in sys.argv:
    print(i)

print('\nПеременная PYTHONPATH\n', sys.path, '\n')

Вначале мы импортируем модуль sys командой import. Этот модуль содержит функции, которые относятся к Python и его среде. Модуль sys встроенные и интерпретатор Python знает где его искать, иначе ему бы пришлось искать по путям указанным в sys.path. Переменная sys.argv является частью модуля sys и аргументы командной строки. Следует знать, что имя запускаемого файла является первым аргументом командной строки.

Импорт модуля - довольно ресурсоемкое действие, так как Python работает с файловой системой ища нужные модули, пусть даже по прописанным путям, потом загружая их в память. Есть способы ускорить этот процесс создавая байткоды с расширением .pyc, которые являются промежуточной формой в которую python переводит программу. В следующий раз, при наличии данного файла, импорт модуля произойдет куда быстрее, так как большая часть будет сделана. Особенностью такого кода является то, что он не зависит от платформы на которой написан.

from .. import

Иногда бывает не нужно импортировать весь модуль, а только его определенные функции и переменные. Такой подход позволяет не писать название модуля, а только имя функции в модуле. То есть вместо sys.argv мы бы писали argv. Но в таком случае часто бывают конфликты имен и следует следить за этим.

# Пример использования
from math import random
from sys import path, argv

...

__name__

Каждый модуль обладает именем. Это может быть полезно, если нужно узнать запущен ли модуль как программа или импортирован. Мы можем использовать это, чтобы заставить вести себя модуль по разному в зависимости от того импортируется ли он или исполняется. Для этого можно использовать имя модуля __name__. Если модуль исполняется, то имени __name__ присваивается значение __main__. Давайте приведем пример:

print('Моё имя: %s' % __name__)

if __name__ == '__main__':
    print('Программа запущена сама по себе')
else:
    print('Модуль импортирован')

При импорте этого модуля переменная __name__ получит значение имени файла не включая остаток .py.

Создавать модули на Python очень легко. Для этого достаточно создать файл с расширением .py. Давайте напишем простой пример:

def hello():
    print('Hello!')

version = '1.0'

Сохраним файл под именем hello.py. Далее давайте попробуем использовать этот модуль:

import hello

hello.hello()
print('Версия: %s' % hello.version)

Как видите использовать модуль довольно просто. Но иногда бывает нужно узнать какие функции, классы, переменные содержит в себе модуль, для этого используется функция dir(). Если мы не передадим в эту функцию переменную, то будет выведен список атрибутов текущего модуля, чтобы посмотреть список атрибутов другого модуля, нужно передать его имя в эту переменную:

dikiigr@dikiigr:~$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sys']
>>> test = 'test'
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sys', 'test']
>>> del test
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sys']
>>> dir(sys)
['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__plen', '__spec__', '__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', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions']
>>>

Пакеты

Иногда бывает нужно объединить модули в некоторую логически связанную сущность - пакет. К примеру django - есть ничто иное как пакет, но организационно сложный. Пакет - это просто папка с модулями и файлом __init__.py, который сообщает нашему интерпретатору, что этот каталог - пакет. Начиная с Python 3.3 такой необходимости больше нет, но все же лучше создавать такой файл для совместимости. Давайте попробуем создать пакет со следующей структурой:

hello\
    __init__.py
    hello-world.py
    vasia\
        __init__.py
        hello-vasia.py

Для того, чтобы импортировать модуль из нужного каталога нужно поставить имя каталога точка имя модуля. Например:

import hello.hello-world
import hello.vasia.hello-vasia

То есть использование пакетов тоже довольно просто. В заключении стоит отметить, что не стоит боятся модулей и пакетов, все это поможет вам лучше понять структуру python программ и легче организовать ваш код.