Python модуль – Модуль числа в Python 3 — Функция abs библиотеки math

Содержание

Модуль числа в Python 3 — Функция abs библиотеки math

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

Модуль числа

Часто в программировании требуется вычислить абсолютное значение числа. Иначе говоря, отбросить знак.

При вычислении модуля возможны 3 ситуации:

  • Когда число больше 0. Если взять его по модулю — не изменится.
  • Модуль нуля так же равен нулю.
  • У отрицательного числа отбрасываем знак. То есть умножаем его на -1.

Но это все справедливо только для действительных чисел. Чему же тогда будет равен модуль комплексных?

Комплексное число состоит из действительной составляющей и мнимой. Геометрически это можно представить как 2 ортогональные оси: действительную и мнимую. Отмечаем на координатных осях требуемую точку. Модулем будет длина отрезка, проведенного из начала координат в эту точку.

Исходя из теоремы Пифагора получаем, что модуль комплексного числа это корень квадратный из суммы квадратов мнимой и действительной частей.

Вычисление

Вычислять модуль можно следующими способами:

  • Используя стандартную функцию abs.
  • С помощью функции fabs библиотеки math.
  • При помощи самостоятельно написанной функции.

Все эти функции работают как в Python 2, так и в Python 3.

abs

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

a = -10
b = abs(a)
print(b)
print(type(b))

10
<class 'int'>

fabs

Можно так же воспользоваться функцией fabs из библиотеки math. Библиотеку можно подключить с помощью from math import fabs.

from math import fabs
a = -10
b = fabs(a)
print(b)
print(type(b))

10.0
<class 'float'>

Отличие abs от fabs заключается в том, что функция abs возвращает значение того же типа, что и аргумент. Функция же fabs вначале преобразует тип аргумента к вещественному числу.

Свое решение

Если по каким то причинам нет возможности или желания использовать стандартные функции, то можно написать свое решение.

Например, можно вычислить воспользоваться тернарным оператором.

a = -10
b = a if a > 0 else -a
print(b)

10

На основе такого условия сделаем свою функцию.

def my_abs(a):
    return a if a > 0 else -a
print(my_abs(-3))

3

Модуль комплексного числа

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

Функцией fabs мы не сможем воспользоваться. Если попытаемся это сделать, то получим ошибку приведения комплексного числа к действительному (TypeError).

from math import fabs
a = -10-2j
b = fabs(a)
print(b)

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    b = fabs(a)
TypeError: can't convert complex to float

А вот с помощью abs преобразование удается.

a = -10-2j
b = abs(a)
print(b)

10.19803902718557

Или же напишем свою функцию:

from math import sqrt
def my_abs_complex(c):
    return sqrt(c.real**2 + c.imag**2)
a = -10-2j
b = my_abs_complex(a)
print(b)

10.198039027185569

Результаты получились одинаковыми. Но нам все равно пришлось подключить библиотеку math для вычисления квадратного корня.

all-python.ru

Модули и пакеты в Python. Глубокое погружение

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

Тема модулей и пакетов уже обсуждалась нами в 13-ом уроке проекта “Python.Уроки”. Основное внимание там было уделено различным способам импортирования модулей, и использованию хранимых в них функций, классов и переменных. Часть информации в этой статье может повторять уже изложенный материал, это сделано для удобства чтения, чтобы не приходилось переключаться между разными источниками.

Введение

В книге “Совершенный Код” Стив Макконнелл формулирует главный технический императив программирования – это управление сложностью. Основная суть, которого заключается в том, что на каждом этапе разработки ПО мы должны прикладывать максимум усилий для того чтобы сложность нашего проекта не “вышла из берегов”. Показателем этого является возможность одновременно удержать в голове основные компоненты проекта на всех уровнях абстракции. В моделировании систем (да и не только там) выделят такой инструмент как

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

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

Модуль может содержать функции (например, модуль с тригонометрическими функциями), классы, объекты классов и переменные – все это будет доступно для других модулей, если правильно импортировать данный. Также в модуле может содержаться программный код, который будет выполняться, если скрипт запустить на исполнение.

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

Быстрый старт

Перейдем к практике. Если вы знакомы с модулями, то можете пропустить этот раздел. Сейчас мы выполним несколько примеров, которые позволят нам получить интуитивное понимание этой темы.

Модули

Создадим модуль с именем simplemath.py, который будет содержать функции для выполнения простых арифметических действий.

simplemath.py

def add(a, b):
   return a + b

def sub(a, b):
   return a - b

def mul(a, b):
   return a * b

def div(a, b):
   return a / b

Создадим ещё один модуль worker.py, который будет использовать функции из simplemath.py. Если мы хотим импортировать все функции, то оператор import для нас отлично подойдет. Это будет выглядеть так.

worker.py

import simplemath

print("\"import\" sample")
print(simplemath.add(1, 2)) print(simplemath.sub(1, 2)) print(simplemath.mul(1, 2)) print(simplemath.div(1, 2))

Получим следующий результат.

"import" sample
3
-1
2
0.5

Если же нам нужна только функция сложения, то в таком случае лучше воспользоваться оператором from.

worker_from.py

from simplemath import add

print("\"from\" sample")
print(add(1, 2))
print(sub(1, 2))

Результат выполнения в этом случае будет такой.

"from" sample
3
Traceback (most recent call last):
  File "C:/worker_from.py", line 5, in <module>
    print(sub(1, 2))
NameError: name 'sub' is not defined

Заметьте, что теперь для вызова функции add() нет необходимости указывать, что она находится в модуле

simplemath. В первом случае мы ее вызывали так simplemath.add(1, 2), теперь достаточно сделать так: add(1, 2). Вызов функции sub(1, 2) завершился неудачей, т.к. мы его не импортировали.

Пакеты

Создадим папку mathpack и перенесем туда модуль simplemath.py. Теперь, для того, чтобы использовать simplemath в нашем проекте, необходимо изменить процедуру импорта. Если мы просто добавим в import simplemath название пакета в виде префикса, то тогда нужно будет и модифицировать все места вызова функций из simplemath.

worker_pack.py

import mathpack.simplemath

print("\"import\" sample")
print(mathpack.simplemath.add(1, 2))
print(mathpack.simplemath.sub(1, 2))
print(mathpack.simplemath.mul(1, 2))
print(mathpack.simplemath.div(1, 2))

Это может быть не очень удобным. Можно модифицировать импорт следующим образом:

from mathpack import simplemath

Тогда в остальном коде ничего не придется менять.

worker_pack_from.py

from mathpack import simplemath

print("\"import\" sample")
print(simplemath.add(1, 2))
print(simplemath.sub(1, 2))
print(simplemath.mul(1, 2))
print(simplemath.div(1, 2))

На этом закончим наш “Быстрый старт” и начнем более детально разбирать темы модулей и пакетов.

Работа импорта – взгляд изнутри

Работа процедуры импорта модуля включает три шага: поиск модуля, компиляция и запуск. Начнем с шага – поиск модуля. Поиска модуля, указанного в импорте, интерпретатор Python, выполняет последовательно в ряде директорий, список которых определен в рамках Module Search Path. Этот список выглядит так:

  • домашняя директория;
  • директории, указанные в переменной окружения PYTHONPATH;
  • директории
    Standard library
    ;
  • пути прописанные в .pth файлах;
  • пакеты сторонних разработчиков.

Домашняя директория – это место, откуда выполняется скрипт. Например, если файлы simplemath.py и worker.py из раздела “Быстрый старт” лежат в директории J:\work, то при запуске скрипта worker.py:

>python j:\work\worker.py

В качестве домашней директории будет выступать  J:\work.

Переменная окружения PYTHONPATH задается также как любая другая переменная окружения в используемой вами операционной системе, в ней перечисляются пути, по которым может находиться модуль, указанный в импорте. Например, если модуль simplemath.py, перенести в каталог J:\work\sm, то попытка запустить worker.py завершится неудачей, т.к. не будет найден модуль simplemath.py. После добавления пути J:\work\sm в PYTHONPATH все будет ОК, только не забудьте перезапустить пользовательский сеанс.

При установке Python на вашем компьютере вместе с интерпретатором установится и  стандартная библиотека (Standard library), вот в ней и будет осуществляться поиск модуля, если он не будет найден в рабочей директории и по путям из переменной окружения PYTHONPATH.

Следующее место, где будет искать модуль интерпретатор Python, если не найдет его в стандартной библиотеке – эти пути, прописанные в файлах с расширением .pth. Это обычные текстовые файлы, в которых указываются пути, по которым необходимо производить поиск модулей (каждый путь должен начинаться с новой строки). Данные файлы следует располагать в каталоге Python или в <python-dir>/lib/site-python. В рамках нашего примера мы удалим в своей системе переменную окружения PYTHONPATH, созданную чуть раньше (если у вас она используется, то можно убрать из нее добавленный нами путь J:\work\sm). После этого создадим в директории C:\Python35-32 файл workerpath.pth со следующим содержимым.

workerpath.pth

j:\work\sm

Этого будет достаточно, чтобы скрипт worker.py запустился удачно.

Ну и последняя на очереди директория, в которой будет осуществляться поиск импортированного модуля – это lib/site-packages. В ней, как правило, располагаются пакеты, от сторонних разработчиков, устанавливаемые средствами Python.

После того, как модуль был найден, производится его компиляция в байт-код, если это необходимо. Это делается в том случае, если байт-код более старый по сравнению с файлом с исходным кодом (или запускается в другом интерпретаторе). В Python 3 после компиляции создается каталог с именем __pycache__, в нем располагаются файлы с расширением .pyc, в них содержится байт-код.

После этого следует процедура запуска модуля, которая заключается в последовательном выполнении строк кода в соответствующем модуле. Важно помнить, что модуль импортируется только один раз, при этом, если вы еще раз выполните процедуру импорта, то модуль загружен не будет. Перезагрузить модуль можно с помощью команды imp.reload.

Модули

Создание и импортирование модулей

Как мы уже говорили ранее модули – это файлы с расширением .py. Если мы импортируем модуль с помощью import, то получаем доступ к глобальным переменным модуля и его функциями.

Например, импортируем модуль с именем module.

import module

Пусть в module содержится глобальная переменная value и функция calc_value(), тогда доступ к ним мы можем получить так.

module.value
module.calc_value()

Такая работа напоминает взаимодействие с объектами классов, когда мы получаем доступа к атрибутам и методам объекта. Имена модулей должны выбираться также как имена переменных, иначе их нельзя будет импортировать. Так, если вы назовете модуль while.py, то импортировать его будет нельзя.

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

Первый способ импорта модуля

import simplemath

Для доступа к элементам simplemath необходимо использовать имя модуля и далее, через точку, как при работе с атрибутами классов, указывать переменные или функции. Вызов add() будет выглядеть так.

simplemath.add(1, 2)

Второй способ импорта модуля

from simplemath import add

В этом случае функцию add() можно вызывать напрямую, без указания имени модуля. При этом остальные функции из simplemath, такие как sub(), mul() и div() будут недоступны.

Третий способ

from simplemath import *

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

Что ещё нужно знать про импорт модулей?

Следует помнить о том, что import и from – это исполняемые выражения, и выполняются они в процессе исполнения скрипта, а не на этапе компиляции. Это позволяет гибко подходить к процессу импортирования: использовать условные выражения и т.п.

В нашем распоряжении есть модуль simplemath.py. Создадим ещё один модуль с иметем advmath.py.

advmath.py

def sqrt(value):
    return value**0.5

def pow(value, magn):
    return value**magn

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

selectimport.py

val = int(input("simple math lib [1], adv math lib [2]: "))
if val==1:
    import simplemath
    print(simplemath.add(1, 2))
elif val==2:
    import advmath
    print(advmath.sqrt(4))
else:
    print("Type only 1 or 2")

Теперь обсудим вопрос модификации данных в импортируемых модулях. Если вы импортируете модуль через оператор import, то в пространстве имен вашей программы появляется объект-модуль с соответствующим именем, аргументы которого – это переменные в модуле.

Создадим модуль vars.py.

vars.py

value = 1
array = [1, 2, 3]

def set_value(new_value):
    value = new_value

def get_value():
    return value

В этом модуле содержатся две переменные (value и array) и две функции (get_value() и set_value()), позволяющие модифицировать и получать значение переменной value.

Если мы импортируем данный модуль с помощью import, то получим следующие возможности.

Доступ к переменным осуществляется через соответствующие атрибуты объекта-модуля.

>>> import vars
>>> vars.value
1
>>> vars.array
[1, 2, 3]

Вывоз функций организован как вызов методов объекта-модуля.

>>> vars.get_value()
1
>>> vars.set_value(5)
>>> vars.get_value()
5

При этом мы можем менять значение переменных из модуля vars напрямую, используя атрибуты.

>>> vars.value = 7
>>> vars.value
7
>>> vars.array[2] = 17
>>> vars.array
[1, 2, 17]

Если же мы импортируем модуль vars через from, то работа с его элементами будет отличаться от рассмотренного выше сценария. Переменные value и array будут скопированы в текущую область видимости. Это приведет к ряду последствий.

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

>>> from vars import *
>>> value
1
>>> array
[1, 2, 3]

Но при этом переменная value – это уже новая переменная в текущей области видимости, т.е. она находится вне контекста модуля vars.

Если мы дополнительно импортируем модуль через import, то можно показать, что модификация value в текущем контексте не затронет переменную value в модуле vars. Импортируем модуль vars через импорт и выведем значение value в нем.

>>> import vars
>>> vars.value
1

Модифицируем value в текущем контексте.

>>> value = 9
>>> value
9
>>> vars.value
1

Это изменение не коснулось value из модуля vars. Теперь изменим vars.value.

>>> vars.value = 11
>>> vars.value
11
>>> value
9

Т.е. value и vars.value – это две разные переменные, значения которых никак не связаны друг с другом. Другое дело мутабельные переменные, в нашем примере – это array.

>>> array
[1, 2, 3]
>>> vars.array
[1, 2, 3]

Пока значения совпадают, так и должно быть. Модифицируем array.

>>> array[1] = 23
>>> array
[1, 23, 3]
>>> vars.array
[1, 23, 3]

Как видно, изменение значения переменной array и текущем контексте приводит к изменению этой переменной в контексте модуля vars. Это связано с тем, что элементы этих списков ссылаются на одни и те же объекты. Более подробно о том как устроены типы в Python см. тут (https://devpractice.ru/python-lesson-3-data-model/).

Этот эффект наблюдается и в обратную сторону.

>>> vars.array[0] = 15
>>> vars.array
[15, 23, 3]
>>> array
[15, 23, 3]

Если вы импортируете в своей программе сразу несколько модулей и есть вероятность совпадения имен функций, классов или переменных в них, то лучше используйте import.

Перезагрузка модуля

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

Импортируем модуль vars.

>>> import vars
>>> vars.value
1

Поменяем в файле vars.py строку value = 1 на value = 7.

>>> # внесли изменения в vars.py
>>> import vars
>>> vars.value
1

Ничего не поменялось.

Для перезагрузки модуля необходимо воспользоваться функцией reload() из модуля imp.

>>> # внесли изменения в vars.py
>>> import vars
>>> vars.value
1

>>> from imp import reload
>>> reload(vars)
<module 'vars' from 'j:\\work\\vars.py'>
>>> vars.value
7

И напоследок, все что импортируется из модуля можно получить через функцию dir().

>>> import vars
>>> dir(vars)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'array', 'get_value', 'set_value', 'value']

Пакеты

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

Если перенести модуль vars.py (см. предыдущий раздел) в каталог simple, то импорт будет выглядеть так.

>>> import simple.vars
>>> simple.vars.value
7

При этом для доступа к элементу value необходимо указывать всю иерархию вложения.

Для того, чтобы каталог стал пакетов в его формальном представлении в рамках языка Python, необходимо в него поместить файл __init__.py. Основное назначение этого файла – это предварительная инициализация пакета, если она необходима. В самом простом случае – он может быть пустым.

Если в файле __init__.py есть какой-то код, то он будет выполнен сразу после выполнения процедуры импорта.

Тема пакетов будет развита более детально несколько позднее!!!

На этом пока все! Со временем, если будет появляться интересная информация, и какие-то полезные практики использования модулей и пакетов, эта статья будет расширяться

devpractice.ru

Pythonicway — Модули в Python

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

Команда import в Python:

Вы можете использовать любой питоновский файл как модуль в другом файле, выполнив в нем команду import. Команда import в Python обладает следующим синтаксисом:

import module_1[, module_2[,... module_N]

Когда интерпретатор Python встречает команду import, он импортирует (дает доступ) этот модуль, если он присутствует в пути поиска Python. Путь поиска Python это список директорий, в которых интерпретатор производит поиск перед попыткой загрузить модуль. Например, чтобы использовать модуль math следует написать:

import math
# Используем функцию sqrt из модуля math
print (math.sqrt(9))
# Печатаем значение переменной pi, определенной в math
print (math.pi)

Важно знать, что модуль загружается лишь однажды, независимо от того, сколько раз он был импортирован. Это препятствует цикличному выполнению содержимого модуля.

Команда from … import в Python

Команда from … import позволяет вам импортировать не весь модуль целиком, а только определенное его содержимое. Например:

# Импортируем из модуля math функцию sqrt
from math import sqrt
# Выводим результат выполнения функции sqrt.
# Обратите внимание, что нам больше незачем указывать имя модуля
print (sqrt(144))

# Но мы уже не можем получить из модуля то, что не импортировали
print (pi) # Выдаст ошибку

Выражение from … import не импортирует весь модуль, а только предоставляет доступ к конкретным объектам, которые мы указали.

Команда from … import * в Python:

В Python так же возможно импортировать всё (переменные, функции, классы) за раз из модуля, для этого используется конструкция from … import *. Например:

from math import *

# Теперь у нас есть доступ ко всем функция и переменным, определенным в модуле math

print (sqrt(121))
print (pi)
print (e)

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

Местонахождение модулей в Python:

Когда вы импортируете модуль, интерпретатор Python ищет этот модуль в следующих местах:

  1. Директория, в которой находится файл, в котором вызывается команда импорта

  2. Если модуль не найден, Python ищет в каждой директории, определенной в консольной переменной PYTHONPATH.

  3. Если и там модуль не найден, Python проверяет путь заданный по умолчанию

Путь поиска модулей сохранен в системном модуле sys в переменной path. Переменная sys.path содержит все три вышеописанных места поиска модулей.

Получение списка всех модулей Python установленных на компьютере:

Для того, чтобы получить список всех модулей, установленных на вашем компьютере достаточно выполнить команду:

help("modules")

Через несколько секунд вы получите список всех доступных модулей.

Создание своего модуля в Python:

Чтобы создать свой модуль в Python достаточно сохранить ваш скрипт с расширением .py Теперь он доступен в любом другом файле. Например, создадим два файла: module_1.py и module_2.py и сохраним их в одной директории. В первом запишем:

def hello():
    print ("Hello from module_1")

А во втором вызовем эту функцию:

from module_1 import hello

hello()

Выполнив код второго файла получим:

Hello from module_1

Функция dir():

Встроенная функция dir() возвращает отсортированный список строк, содержащих все имена, определенные в модуле.

# на данный момент нам доступны лишь встроенные функции
dir()
# импортируем модуль math
import math
# теперь модуль math в списке доступных имен
dir()
# получим имена, определенные в модуле math
dir(math)

Архитектура программы на Python:

Код на Python может быть организован следующим образом:

  1. Первый уровень это обычные команды на Python.
  2. Команды на Python могут быть собраны в функции.
  3. Функции могут быть частью класса.
  4. Классы могут быть определены внутри модулей.
  5. Наконец, модули могут составляться в пакеты модулей.

Пакеты модулей в Python:

Отдельные файлы-модули с кодом на Python могут объединяться в пакеты модулей. Пакет это директория (папка), содержащая несколько отдельных файлов-скриптов. 

Например, имеем следующую структуру:

|_ my_file.py

|_ my_package

         |_ __init__.py

         |_ inside_file.py

В файле inside_file.py определена некая функция foo. Тогда чтобы получить доступ к функции foo, в файле my_file следует выполнить следующий код:

from my_package.inside_file import foo

Так же обратите внимание на наличие внутри директории my_package файла __init__.py. Это может быть пустой файл, который сообщает Python, что данная директория является пакетом модулей. В Python 3.3 и выше включать файл __init__.py в пакет модулей стало необязательно, однако, рекомендуется делать это ради поддержки обратной совместимости.

 

pythonicway.com

Программирование на Python: Часть 5. Модули

Сергей Яковлев
Опубликовано 16.08.2010

Comments

Серия контента:

Этот контент является частью # из серии # статей:

https://www.ibm.com/developerworks/ru/library/?series_title_by=**auto**

Следите за выходом новых статей этой серии.

Этот контент является частью серии:

Следите за выходом новых статей этой серии.

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

Модули выполняют как минимум три важных функции:

  • Повторное использование кода: такой код может быть загружен много раз во многих местах.
  • Управление адресным пространством: модуль — это высокоуровневая организация программ, это пакет имен, который избавляет вас от конфликтов. Каждый объект «проживает» свой цикл внутри своего модуля, поэтому модуль — это средство для группировки системных компонентов.
  • Глобализация сервисов и данных: для реализации объекта, который используется во многих местах, достаточно написать один модуль, который будет импортирован.

Cегодня мы рассмотрим следующие темы.

  1. Что такое модуль.
  2. Как импортировать модуль.
  3. Что такое компиляция.
  4. Стандартные модули.
  5. Пакеты.

1. Что такое модуль

Python позволяет поместить классы, функции или данные в отдельный файл и использовать их в других программах. Такой файл называется модулем. Объекты из модуля могут быть импортированы в другие модули. Имя файла образуется путем добавления к имени модуля расширения .py. При импорте модуля интерпретатор ищет файл с именем my_module.py сначала в текущем каталоге, затем в каталогах, указанных в переменной окружения PYTHONPATH, затем в зависящих от платформы путях по умолчанию, а также в специальных файлах с расширением ‘.pth’, которые лежат в стандартных каталогах. Программист может внести изменения в PYTHONPATH и в ‘.pth’, добавив туда свой путь. Каталоги, в которых осуществляется поиск, можно посмотреть в переменной sys.path.

Большие программы, как правило, состоят из стартового файла — файла верхнего уровня, и набора файлов-модулей. Главный файл занимается контролем программы. В то же время модуль — это не только физический файл. Модуль представляет собой коллекцию компонентов. В этом смысле модуль — это пространство имен, — namespace, и все имена внутри модуля еще называются атрибутами — такими, например, как функции и переменные.

2. Импорт модуля

Если запустить в каталоге, в котором лежит данный модуль (например, my_module.py), интерпретатор:

>>> python

и потом сделать импорт модуля:

>>> import my_module

то мы получаем доступ ко всем функциям, которые в модуле определены:

>>> my_module.func1()
>>> my_module.func2()
...

Для более короткой записи можно создать локальную переменную:

>>> f1 = my_module.func1

Второй вариант импорта — взятие непосредственно имени без имени модуля:

>>> from my_module import func1, func2
>>> func1()

Третий вариант импорта — включение всех имен, определенных в модуле:

>>> from my_module import *
>>> func1()

Для предотвращения конфликта имен можно использовать создание алиаса:

>>> from my_module import open as my_open

Пример. Импорт на основе from обладает такой особенностью, что он делает импортируемые атрибуты read-only:

>>> from small import x, y
>>> x = 42

В данном случае x — это локальная переменная, в то время как переменные x, y в самом модуле small не меняются:

>>> import small
>>> small.x = 42

здесь x — глобальная переменная.

Во избежание недоразумений import предпочтительнее без from в тех случаях, когда один и тот же модуль используется в нескольких местах.

Поскольку модуль загружается один раз, для его повторной загрузки можно использовать функцию reload().

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

Модули могут импортировать другие модули. Обычно инструкцию import располагают в начале модуля или программы.

3. Компиляция файлов

Для ускорения запуска программ, использующих большое количество модулей, если уже существует файл с именем my_module.pyc в том же каталоге, где найден my_module.py, считается, что он содержит байт-компилированный модуль my_module. Если такого файла нет, то он создается, и время последнего изменения my_module.py записывается в созданном my_module.pyc. Содержимое байт-компилированных файлов является платформенно-независимым (но может быть разным для разных версий интерпретатора), так что каталог с модулями может совместно использоваться машинами с разными архитектурами.

Некоторые полезные опции компиляции:

  1. -O — эта опция заставляет интерпретатор компилировать так называемый оптимизированный байт-код и сохранять его в файле с расширением ‘.pyo’. При этом из кода удаляются ассерты, игнорируется условный дебаг, ‘.pyc’-файлы игнорируются.
  2. -OO — эта опция делает то же, что и предыдущая опция, плюс удаляет комменты.
  3. Файл, запускаемый непосредственно из командной строки, никогда не компилируется. Для оптимизации его запуска необходимо большую часть кода убрать в модули.
  4. Модуль может загружаться из файлов с расширением ‘.pyс’ или ‘.pyo’, даже если нет файла с расширением ‘.py’. Это может пригодиться в тех случаях, когда вы не хотите распространять исходный код.
  5. Кроме того, интерпретатор может загружать бинарники, собранные с помощью языка си — файлы с расширением ‘.so’ в линуксе либо ‘.dll’ в Windows.
  6. Модуль можно «зазипповать» в архив с расширением ‘.zip’ и импортировать из архива.
  7. Может быть загружен Java-класс, собранный с помощью Jython.

4. Стандартные модули

Python распространяется с библиотекой стандартных модулей. Библиотека включает в себя более 200 модулей, которые выполняют платформенно-зависимую поддержку таких задач, как: интерфейс к операционной системе, управление объектами, поиск, сеть + интернет, GUI и т.д. Полный список стандартных модулей можно посмотреть на http://docs.python.org/library/.

Часть модулей встроена в интерпретатор по умолчанию, обеспечивая доступ к операциям; они встроены либо из соображений эффективности, либо для обеспечения доступа к примитивам операционной системы — например, модуль sys.

Переменная sys.path содержит список строк с именами каталогов, в которых происходит поиск модулей. Она инициализируется из значения переменной окружения PYTHONPATH и встроенного значения по умолчанию. Можно добавить путь:

>>> import sys
>>> sys.path.append(/home/my/lib/python)

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

>>> dir(sys)
['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__name__',
...
'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info']

5. Пакеты

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

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

Например, есть пакет, который лежит в корневой папке TCP. В нем лежат два подкаталога — Server и Client:

TCP/
   _init_.py
   main.py
   
   Server/
         _init_.py
         tcp.py
         server.py
         lib.py
   Client/
         _init_.py
         tcp.py
         client.py
         lib.py

Файл _init_.py необходим для того, чтобы интерпретатор распознал каталог, как содержащий пакет. Обычно это пустой файл. Тогда импорт индивидуальных модулей пакета может быть таким:

>>> import TCP.Server.lib
>>> import TCP.Client.lib

Ссылка на функцию должна быть полной:

>>> import TCP.Server.lib.connect()

Можно сделать альтернативную загрузку:

>>> from TCP.Server import lib as server_lib 
>>> from TCP.Client import lib as client_lib 
>>> server_lib.connect()
>>> client_lib.connect()

Здесь вместо lib может быть подставлен модуль, подпакет или имя, определенное в TCP.Server — т.е. это может быть функция, класс или переменная.

Что касается варианта с импортом:

>>> from TCP import *

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

    __all__ = ["Server", "Client"]

Импорт всех имен может привести к конфликтам. При этом глобальные переменные становятся доступными только на чтение — вместо них будут созданы локальные.

Заключение

Сегодня мы узнали основы модульной системы питона и импорта компонентов. Импорт модулей — это основа программной архитектуры в питоне. Большие программы состоят из большого количества файлов, и объединяет их линковка во время исполнения на основе импорта. Модули структурируют программу, разбивая логику на отдельные компоненты. Код внутри одного модуля изолирован от остальных модулей, что минимизирует коллизию имен внутри программы.

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

<< Предыдущая статья. Следующая статья >>

Ресурсы для скачивания

Подпишите меня на уведомления к комментариям

www.ibm.com

Крутые модули Python, которые вы не используете, а надо бы

Какие методы и модули Python сделают ваш код чище и эффективнее? Рассмотрим 5 скрытых жемчужин стандартной библиотеки Python.

Язык Python – прекрасен, и содержит много встроенных модулей, которые помогают сделать код более качественным и красивым.

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

Полагаем, некоторые из вас уже знакомы с более популярным именованным кортежем namedtuple из модуля collections (если нет – ознакомьтесь). Но начиная с Python 3.6, в модуле typing доступен новый класс: NamedTuple. Оба предназначены для быстрого создания читаемых неизменяемых объектов.

NamedTuple – на самом деле типизированная версия namedtuple и, по мнению разработчика, этот класс гораздо более читаемый:

In [2]: import typing                                                                                                                                                                                               

In [3]: class BetterLookingArticle(typing.NamedTuple): 
   ...:     title: str 
   ...:     id: int 
   ...:     description: str = "No description given." 
   ...:                                                                                                                                                                                                             

In [4]: BetterLookingArticle(title="Python is cool.", id=1)                                                                                                                                                  
BetterLookingArticle(title='Python is cool.', id=1, description='No description given.')

Вот альтернатива c использованием namedtuple:

In [6]: import collections                                                                                                                                                                                          

In [7]: Article = collections.namedtuple("Article", ["title", "description", "id"])                                                                                                                                 

In [8]: Article(title="Python is cool.", id=1, description="")                                                                                                                                               
Article(title='Python is cool.', description='', id=1)

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

Когда используется модуль array, создание массива происходит с указанием типа данных, который будут использовать все его элементы. Давайте сравним время выполнения кода с обычным списком, записав много целых чисел в файл (используя модуль pickle для обычного списка):

https://gist.github.com/AdamGold/961758c66cdfe92642eabb61d9ce9866

В 14 раз быстрее. Это много. Конечно, время выполнения также зависит и от модуля pickle, но всё же массив гораздо компактнее, чем список. Поэтому, если используете простые числовые значения, рассматривайте использование модуля array.

itertools – впечатляющий модуль. У него так много разных методов, позволяющих экономить время. Есть даже репозиторий GitHub, содержащий ещё больше подобных инструментов.

Давайте посмотрим на метод combinations. Он принимает в качестве аргументов итерируемый объект и целое число. В результате получаем генератор, состоящий из всех возможных комбинаций итерируемого объекта. Максимальная длина последовательности равна указанному целому числу. Сочетания не дублируются:

In [16]: import itertools                                                                                                                                                                                           
In [17]: list(itertools.combinations([1, 2, 3, 4], 2))                                                                                                                                                       
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

Быстрый и красивый способ создания словаря со значениями по умолчанию:

In [18]: dict.fromkeys(["key1", "key2", "key3"], "DEFAULT_VALUE")                                                                                                                                            
{'key1': 'DEFAULT_VALUE', 'key2': 'DEFAULT_VALUE', 'key3': 'DEFAULT_VALUE'}

Модуль dis обеспечивает анализ байт-кода CPython путём его дизассемблирования.

Как вы наверняка знаете, Python компилирует исходный код в набор инструкций под названием «байт-код». Модуль dis помогает обрабатывать эти инструкции. И это отличный инструмент для отладки.

Вот пример из книги «Fluent Python»:

In [22]: t = (1, 2, [3, 4])                                                                                                                                                                                         
In [23]: t[2] += [30, 40]                                                                                                                                                                                           
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-af836a8d44a2> in <module>
----> 1 t[2] += [30, 40]

TypeError: 'tuple' object does not support item assignment

In [24]: t                                                                                                                                                                                                          
Out[24]: (1, 2, [3, 4, 30, 40])

Получили ошибку, но операция всё равно завершилась. Как так? Узнаем, если посмотрим на байт-код (добавлены комментарии рядом с важными частями):

In [25]: dis.dis("t[a] += b")                                                                                                                                                                                       
  1           0 LOAD_NAME                0 (t)
              2 LOAD_NAME                1 (a)
              4 DUP_TOP_TWO
              6 BINARY_SUBSCR
              8 LOAD_NAME                2 (b)
             10 INPLACE_ADD --> (value in t[a]) += b --> выполняется, так как список изменяемый
             12 ROT_THREE
             14 STORE_SUBSCR --> Assign t[a] = our list --> Ошибка, t[a] неизменяемый.
             16 LOAD_CONST               0 (None)
             18 RETURN_VALUE

Это перевод статьи на Medium.

А какие крутые модули Python знаете вы? Делитесь в комментариях.

proglib.io

Модуль math | Python 3 для начинающих и чайников

Модуль math – один из наиважнейших в Python. Этот модуль предоставляет обширный функционал для работы с числами.

math.ceil(X) – округление до ближайшего большего числа.

math.copysign(X, Y) — возвращает число, имеющее модуль такой же, как и у числа X, а знак — как у числа Y.

math.fabs(X) — модуль X.

math.factorial(X) — факториал числа X.

math.floor(X) — округление вниз.

math.fmod(X, Y) — остаток от деления X на Y.

math.frexp(X) — возвращает мантиссу и экспоненту числа.

math.ldexp(X, I) — X * 2i. Функция, обратная функции math.frexp().

math.fsum(последовательность) — сумма всех членов последовательности. Эквивалент встроенной функции sum(), но math.fsum() более точна для чисел с плавающей точкой.

math.isfinite(X) — является ли X числом.

math.isinf(X) — является ли X бесконечностью.

math.isnan(X) — является ли X NaN (Not a Number — не число).

math.modf(X) — возвращает дробную и целую часть числа X. Оба числа имеют тот же знак, что и X.

math.trunc(X) — усекает значение X до целого.

math.exp(X) — eX.

math.expm1(X) — eX — 1. При X → 0 точнее, чем math.exp(X)-1.

math.log(X, [base]) — логарифм X по основанию base. Если base не указан, вычисляется натуральный логарифм.

math.log1p(X) — натуральный логарифм (1 + X). При X → 0 точнее, чем math.log(1+X).

math.log10(X) — логарифм X по основанию 10.

math.log2(X) — логарифм X по основанию 2. Новое в Python 3.3.

math.pow(X, Y) — XY.

math.sqrt(X) — квадратный корень из X.

math.acos(X) — арккосинус X. В радианах.

math.asin(X) — арксинус X. В радианах.

math.atan(X) — арктангенс X. В радианах.

math.atan2(Y, X) — арктангенс Y/X. В радианах. С учетом четверти, в которой находится точка (X, Y).

math.cos(X) — косинус X (X указывается в радианах).

math.sin(X) — синус X (X указывается в радианах).

math.tan(X) — тангенс X (X указывается в радианах).

math.hypot(X, Y) — вычисляет гипотенузу треугольника с катетами X и Y (math.sqrt(x * x + y * y)).

math.degrees(X) — конвертирует радианы в градусы.

math.radians(X) — конвертирует градусы в радианы.

math.cosh(X) — вычисляет гиперболический косинус.

math.sinh(X) — вычисляет гиперболический синус.

math.tanh(X) — вычисляет гиперболический тангенс.

math.acosh(X) — вычисляет обратный гиперболический косинус.

math.asinh(X) — вычисляет обратный гиперболический синус.

math.atanh(X) — вычисляет обратный гиперболический тангенс.

math.erf(X) — функция ошибок.

math.erfc(X) — дополнительная функция ошибок (1 — math.erf(X)).

math.gamma(X) — гамма-функция X.

math.lgamma(X) — натуральный логарифм гамма-функции X.

math.pi — pi = 3,1415926…

math.e — e = 2,718281…

pythonworld.ru

Работа с модулями: создание, подключение инструкциями import и from

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

Каждая программа может импортировать модуль и получить доступ к его классам, функциям и объектам. Нужно заметить, что модуль может быть написан не только на Python, а например, на C или C++.

Подключение модуля из стандартной библиотеки

Подключить модуль можно с помощью инструкции import. К примеру, подключим модуль os для получения текущей директории:

>>> import os
>>> os.getcwd()
'C:\\Python33'

После ключевого слова import указывается название модуля. Одной инструкцией можно подключить несколько модулей, хотя этого не рекомендуется делать, так как это снижает читаемость кода. Импортируем модули time и random.

>>> import time, random
>>> time.time()
1376047104.056417
>>> random.random()
0.9874550833306869

После импортирования модуля его название становится переменной, через которую можно получить доступ к атрибутам модуля. Например, можно обратиться к константе e, расположенной в модуле math:

>>> import math
>>> math.e
2.718281828459045

Стоит отметить, что если указанный атрибут модуля не будет найден, возбудится исключение AttributeError. А если не удастся найти модуль для импортирования, то ImportError.

>>> import notexist
Traceback (most recent call last):
  File "", line 1, in
    import notexist
ImportError: No module named 'notexist'
>>> import math
>>> math.Ё
Traceback (most recent call last):
  File "", line 1, in
    math.Ё
AttributeError: 'module' object has no attribute 'Ё'

Использование псевдонимов

Если название модуля слишком длинное, или оно вам не нравится по каким-то другим причинам, то для него можно создать псевдоним, с помощью ключевого слова as.

>>> import math as m
>>> m.e
2.718281828459045

Теперь доступ ко всем атрибутам модуля math осуществляется только с помощью переменной m, а переменной math в этой программе уже не будет (если, конечно, вы после этого не напишете import math, тогда модуль будет доступен как под именем m, так и под именем math).

Инструкция from

Подключить определенные атрибуты модуля можно с помощью инструкции from. Она имеет несколько форматов:

from <Название модуля> import <Атрибут 1> [ as <Псевдоним 1> ], [<Атрибут 2> [ as <Псевдоним 2> ] ...]
from <Название модуля> import *

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

>>> from math import e, ceil as c
>>> e
2.718281828459045
>>> c(4.6)
5

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

>>> from math import (sin, cos,
...           tan, atan)

Второй формат инструкции from позволяет подключить все (точнее, почти все) переменные из модуля. Для примера импортируем все атрибуты из модуля sys:

>>> from sys import *
>>> version
'3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]'
>>> version_info
sys.version_info(major=3, minor=3, micro=2, releaselevel='final', serial=0)

Следует заметить, что не все атрибуты будут импортированы. Если в модуле определена переменная __all__ (список атрибутов, которые могут быть подключены), то будут подключены только атрибуты из этого списка. Если переменная __all__ не определена, то будут подключены все атрибуты, не начинающиеся с нижнего подчёркивания. Кроме того, необходимо учитывать, что импортирование всех атрибутов из модуля может нарушить пространство имен главной программы, так как переменные, имеющие одинаковые имена, будут перезаписаны.

Создание своего модуля на Python

Теперь пришло время создать свой модуль. Создадим файл mymodule.py, в которой определим какие-нибудь функции:

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

def fib(n):
    a = b = 1
    for i in range(n - 2):
        a, b = b, a + b
    return b

Теперь в этой же папке создадим другой файл, например, main.py:

import mymodule

mymodule.hello()
print(mymodule.fib(10))

Выведет:

Hello, world!
55

Поздравляю! Вы сделали свой модуль! Напоследок отвечу ещё на пару вопросов, связанных с созданием модулей:

Как назвать модуль?

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

Куда поместить модуль?

Туда, где его потом можно будет найти. Пути поиска модулей указаны в переменной sys.path. В него включены текущая директория (то есть модуль можно оставить в папке с основной программой), а также директории, в которых установлен python. Кроме того, переменную sys.path можно изменять вручную, что позволяет положить модуль в любое удобное для вас место (главное, не забыть в главной программе модифицировать sys.path).

Можно ли использовать модуль как самостоятельную программу?

Можно. Однако надо помнить, что при импортировании модуля его код выполняется полностью, то есть, если программа что-то печатает, то при её импортировании это будет напечатано. Этого можно избежать, если проверять, запущен ли скрипт как программа, или импортирован. Это можно сделать с помощью переменной __name__, которая определена в любой программе, и равна «__main__», если скрипт запущен в качестве главной программы, и имя, если он импортирован. Например, mymodule.py может выглядеть вот так:

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

def fib(n):
    a = b = 1
    for i in range(n - 2):
        a, b = b, a + b
    return b

if __name__ == "__main__":
    hello()
    for i in range(10):
        print(fib(i))

pythonworld.ru

Оставить комментарий

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

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