Работа с пакетами в python

Python. Урок 13. Модули и пакеты

Follow us on Google Plus Follow us on rss

Модули и пакеты значительно упрощают работу программиста. Классы, объекты, функции и константы, которыми приходится часто пользоваться можно упаковать в модуль, и, в дальнейшем, загружать его в свои программы при необходимости. Пакеты позволяют формировать пространства имен для работы с модулями.

Модули в Python

Что такое модуль в Python?

Под модулем в Python понимается файл с расширением .py. Модули предназначены для того, чтобы в них хранить часто используемые функции, классы, константы и т.п. Можно условно разделить модули и программы: программы предназначены для непосредственного запуска, а модули для импортирования их в другие программы. Стоит заметить, что модули могут быть написаны не только на языке Python, но и на других языках (например C).

Как импортировать модули в Python?

Самый простой способ импортировать модуль в Python это воспользоваться конструкцией:

import имя_модуля

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

>>> import math >>> math.factorial(5) 120

За один раз можно импортировать сразу несколько модулей, для этого их нужно перечислить через запятую после слова import:

import имя_модуля1, имя_модуля2

>>> import math, datetime >>> math.cos(math.pi/4) 0.707106781186547 >>> datetime.date(2017, 3, 21) datetime.date(2017, 3, 21)

Если вы хотите задать псевдоним для модуля в вашей программе, можно воспользоваться вот таким синтаксисом:

import имя_модуля as новое_имя

>>> import math as m >>> m.sin(m.pi/3) 0.866025403784438

Используя любой из вышеперечисленных подходов, при вызове функции из импортированного модуля, вам всегда придется указывать имя модуля (или псевдоним). Для того, чтобы этого избежать делайте импорт через конструкцию from … import…

from имя_модуля import имя_объекта

>>> from math import cos >>> cos(3.14) 0.999998731727539

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

>>> from math import cos >>> cos(3.14) -0.999998731727539 >>> sin(3.14) Traceback (most recent call last): File "", line 1, in module> sin(3.14) NameError: name 'sin' is not defined >>> math.sin(3.14) Traceback (most recent call last): File "", line 1, in module> math.sin(3.14) NameError: name 'math' is not defined

Для имортирования нескольких функций из модуля, можно перечислить их имена через запятую.

from имя_модуля import имя_объекта1, имя_объекта2

>>> from math import cos, sin, pi >>> cos(pi/3) 0.500000000000000 >>> sin(pi/3) 0.866025403784438

Импортируемому объекту можно задать псевдоним.

from имя_модуля import имя_объекта as псевдоним_объекта

>>> from math import factorial as f >>> f(4) 24

Если необходимо импортировать все фукнции, классы и т.п. из модуля, то воспользуйтесь следующей формой оператора from … import …

from имя_модуля import *

>>> from math import * >>> cos(pi/2) 6.123233995736766e-17 >>> sin(pi/4) 0.707106781186547 >>> factorial(6) 720

Пакеты в Python

Что такое пакет в Python?

Пакет в Python – это каталог, включающий в себя другие каталоги и модули, но при этом дополнительно содержащий файл __init__.py. Пакеты используются для формирования пространства имен, что позволяет работать с модулями через указание уровня вложенности (через точку).

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

Использование пакетов в Python

Рассмотрим следующую структуру пакета:

fincalc |-- __init__.py |-- simper.py |-- compper.py |-- annuity.py

Пакет fincal содержит в себе модули для работы с простыми процентами ( simper.py ), сложными процентами ( compper.py ) и аннуитетами ( annuity.py ).

Для использования фукнции из модуля работы с простыми процентами, можно использовать один из следующих вариантов:

import fincalc.simper fv = fincalc.simper.fv(pv, i, n)
import fincalc.simper as sp fv =sp.fv(pv, i, n)
from fincalc import simper fv = simper.fv(pv, i, n)

Файл __init__.py может быть пустым или может содержать переменную __all__, хранящую список модулей, который импортируется при загрузке через конструкцию

from имя_пакета import *

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

__all__ = ["simper", "compper", "annuity"]

P.S.

Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.

Источник

Python модули и пакеты

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

После разделения кода по файлам, следует выстроить их взаимодействие. В языке программирования Python данный механизм реализуется с использованием import. Импортировать можно любые компоненты(если Вы кодом не ограничивали таковые) модулей или пакетов.

Модули также могут быть написаны и на других языках, но данная статья направлена на рассмотрение использования данного механизмах в рамках Python.

Модули

В языке программирования Python модулями являются все файлы с расширением *.py (* обозначает, что на этом месте может стоять любой символ или любое их количество). Исключением является служебный файл __init__.py (о назначении которого описано далее в статье).

Дальше стоит понимать, что любая программа имеет некую точку входа. Это своего рода место с которого стартует наш скрипт. В языках предшественниках данной точкой служила функция main и могла быть лишь только одной. В нашем случае допускается отсутствие таковой, но это снижает качество кода, делая его сложным и малопредсказуемым(при импорте код содержащийся на верхнем уровне исполняется). Для того чтобы указать точку входа(может быть указана только в модулях) используется специальная переменная __name__ , в которой содержится наименование текущего модуля или пакета. Если текущий модуль находится на верхнем уровне исполнения(мы явно его передали на исполнение Python), то он называется __main__ независимо от названия файла.

# Указание входной точки ## Если __name__ равно "__main__" исполни if __name__ == "__main__": print('Я главный!') # Вызов других функций, например main()

Для примера реализуем простой модуль, который будет возвращать нам информацию:

# http_get.modules.http_get # Расположен в дирректории http_get, modules и назван http_get def get_dict(): return # Поскольку зависимых импортов нет, мы можем исполнить этот код для проверки # Т.е. в качестве входной точки использовать нашу функцию # Данный код исполнится только, когда этот файл будет исполняемым(не импортируемым) if __name__ == '__main__': print(get_dict())

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

# main.py from ModulesAndPackages.module_examples.http_get.modules.http_get import get_dict as absolute from http_get.modules.http_get import get_dict as relative def main(): # Работает print(absolute()) print(relative()) if __name__ == '__main__': main()

Все без проблем исполняется.

Трудности

При переносе файлов куда-либо из директории возникнут проблемы из-за первого импорта( main.py ). Поскольку часто приходится писать один и тот же код, использование уже хорошо написанного пакета или модуля может экономить много времени, но исправление большого количества импортов требует Ваших ресурсов. Хорошо написанный пакет, модуль или импорт может экономить ваши рабочие часы, а иногда и нервы.

Не изменяя наши модули(импорты), при изменении положения файлов возникает ошибка импорта:

# Не работает в другом проекте from ModulesAndPackages.module_examples.http_get.modules.http_get import get_dict as absolute # Всегда работает from http_get.modules.http_get import get_dict as relative def main(): print(absolute()) print(relative()) if __name__ == '__main__': main()

Пакеты

В языке программирования Python пакетами являются все директории(вне зависимости от наличия в них модулей), содержащие файл __init__.py , который исполняется при импорте пакета и несет его название ( __name__ ).

Для примера реализуем простой пакет( package ), на базе вышеописанного модуля( http_get.py ):

# package/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package/__init__.py from .modules.http_get import get_dict . def get_data(): return get_dict() . # Не работает # __init__ не может иметь точки входа # # if __name__ == '__main__': # get_data()

А также реализуем простой пакет с такой же логикой, но с использованием абсолютного импорта:

# package_2/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict()) 
# package_2/__init__.py from ModulesAndPackages.package_examples.package_2.modules.http_get import get_dict . def get_data(): return get_dict() . # Не работает # __init__ не может иметь точки входа # # if __name__ == '__main__': # get_data()

В корне директории(на уровень выше пакета) создадим файл, в котором воспользуемся нашими пакетами( main.py ):

# main.py from package import get_data from package_2 import get_data as get_data_2 def main(): # Работает print(get_data()) print(get_data_2()) if __name__ == '__main__': main()

Трудности

Но при переносе нашего package_2 в другой проект, он теряет свою работоспособность из-за ошибки импортирования в __init__.py файле, в отличии от package .

# package_transferring/package/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package_transferring/package/__init__.py from .modules.http_get import get_dict . def get_data(): return get_dict() . # Не работает # __init__ не может иметь точки входа # # if __name__ == '__main__': # get_data()
# package_transferring/package_2/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package_transferring/package_2/__init__.py # Ошибка импорта т.к. изменилась директория from ModulesAndPackages.package_examples.package_2.modules.http_get import get_dict . def get_data(): return get_dict() . # Does not work! # Because init file in package could not have entry point # # if __name__ == '__main__': # get_data()
# package_transferring/main.py from package import get_data # Ошибка импорта from package_2 import get_data as get_data_2 def main(): print(get_data()) print(get_data_2()) if __name__ == '__main__': main()

P.S.

Данная статья написана для новичков, которые изучают язык программирования Python. Задача которой продемонстрировать на простых примерах способы написания пакетов и модулей(не является туториалом), а так же показать какие трудности могут возникнуть и пути их решения.

Github с проектом к данной статье: ModulesAndPackages

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

Источник

Читайте также:  And or xor cpp
Оцените статью