Get started learning Python with DataCamp's free Intro to Python tutorial. Learn Data Science by completing interactive coding challenges and watching videos by expert instructors. Start Now!
This site is generously supported by DataCamp. DataCamp offers online interactive Python Tutorials for Data Science. Join 11 million other learners and get started learning Python for data science today!
Good news! You can save 25% off your Datacamp annual subscription with the code LEARNPYTHON23ALE25 - Click here to redeem your discount
Модули и пакеты
В программировании модуль — это часть программного обеспечения с определенной функциональностью. Например, при создании игры в пинг-понг один модуль может отвечать за логику игры, а другой модуль рисует игру на экране. Каждый модуль состоит из разного файла, который может редактироваться отдельно.
Writing modules
Модули в Python — это просто файлы Python с расширением .py. Имя модуля такое же, как и имя файла. Python-модуль может содержать набор функций, классов или переменных, которые определены и реализованы. В приведенном выше примере есть два файла:
mygame/
-
mygame/game.py
-
mygame/draw.py
Python-скрипт game.py
реализует игру. Он использует функцию draw_game
из файла draw.py
или, другими словами, модуль draw
, который реализует логику рисования игры на экране.
Модули импортируются из других модулей с помощью команды import
. В этом примере скрипт game.py
может выглядеть следующим образом:
# game.py
# импортируем модуль draw
import draw
def play_game():
...
def main():
result = play_game()
draw.draw_game(result)
# это означает, что если этот скрипт выполнен, то будет выполнен main()
if __name__ == '__main__':
main()
Модуль draw
может выглядеть следующим образом:
# draw.py
def draw_game():
...
def clear_screen(screen):
...
В этом примере модуль game
импортирует модуль draw
, который позволяет ему использовать функции, реализованные в этом модуле. Функция main
использует локальную функцию play_game
для запуска игры, а затем рисует результат игры с помощью функции draw_game
, реализованной в модуле draw
. Чтобы использовать функцию draw_game
из модуля draw
, мы должны указать, в каком модуле реализована функция, с помощью оператора точки. Чтобы обратиться к функции draw_game
из модуля game
, мы должны импортировать модуль draw
, а затем вызвать draw.draw_game()
.
Когда выполняется директива import draw
, интерпретатор Python ищет файл в каталоге, в котором был выполнен скрипт, с именем модуля и суффиксом .py
. В этом случае он будет искать draw.py
. Если он найден, он будет импортирован. Если его не найдут, будет продолжен поиск встроенных модулей.
Вы, возможно, заметили, что при импорте модуля создается файл .pyc
. Это скомпилированный файл Python. Python компилирует файлы в байт-код Python, чтобы не пришлось анализировать файлы каждый раз, когда модули загружаются. Если файл .pyc
существует, он загружается вместо файла .py
. Этот процесс прозрачен для пользователя.
Importing module objects to the current namespace
Пространство имен — это система, в которой каждый объект имеет имя и к нему можно получить доступ в Python. Мы импортируем функцию draw_game
в пространство имен главного скрипта, используя команду from
.
# game.py
# импортируем модуль draw
from draw import draw_game
def main():
result = play_game()
draw_game(result)
Вы могли заметить, что в этом примере имя модуля не предшествует draw_game
, поскольку мы указали имя модуля с помощью команды import
.
Преимущества этой нотации заключаются в том, что вам не нужно ссылаться на модуль снова и снова. Однако пространство имен не может иметь два объекта с одним и тем же именем, поэтому команда import
может заменить существующий объект в пространстве имен.
Importing all objects from a module
Вы можете использовать команду import *
, чтобы импортировать все объекты из модуля, как это:
# game.py
# импортируем модуль draw
from draw import *
def main():
result = play_game()
draw_game(result)
Это может быть немного рискованно, поскольку изменения в модуле могут повлиять на модуль, который его импортирует, но это короче и не требует от вас указывать каждый объект, который вы хотите импортировать из модуля.
Custom import name
Модули могут быть загружены под любым именем, которое вы хотите. Это полезно, когда модуль импортируется условно для использования с тем же именем в остальной части кода.
Например, если у вас есть два модуля draw
с немного разными именами, вы можете сделать следующее:
# game.py
# импортируем модуль draw
if visual_mode:
# в визуальном режиме мы используем графику
import draw_visual as draw
else:
# в текстовом режиме мы выводим текст
import draw_textual as draw
def main():
result = play_game()
# это может быть как визуальный, так и текстовой, в зависимости от visual_mode
draw.draw_game(result)
Module initialization
Первый раз, когда модуль загружается в выполняющийся Python-скрипт, он инициализируется путем выполнения кода в модуле один раз. Если в вашем коде еще один модуль вновь импортирует тот же модуль, он не будет загружен снова, поэтому локальные переменные в модуле действуют как "одиночка", то есть инициализируются только один раз.
Вы можете использовать это для инициализации объектов. Например:
# draw.py
def draw_game():
# при очистке экрана мы можем использовать основной объект экрана, инициализированный в этом модуле
clear_screen(main_screen)
...
def clear_screen(screen):
...
class Screen():
...
# инициализируем main_screen как одиночку
main_screen = Screen()
Extending module load path
Есть несколько способов указать интерпретатору Python, где искать модули, кроме стандартного локального каталога и встроенных модулей. Вы можете использовать переменную окружения PYTHONPATH
, чтобы указать дополнительные каталоги для поиска модулей, как это:
PYTHONPATH=/foo python game.py
Это выполняет game.py
и позволяет скрипту загружать модули из каталога foo
и локального каталога.
Вы также можете использовать функцию sys.path.append
. Выполните ее до выполнения команды import
:
sys.path.append("/foo")
Теперь каталог foo
добавлен в список путей, по которым ищутся модули.
Exploring built-in modules
Посмотрите полный список встроенных модулей в стандартной библиотеке Python здесь.
Две очень важные функции бывают полезны при изучении модулей в Python - функции dir
и help
.
Чтобы импортировать модуль urllib
, который позволяет получать данные с URL, мы import
модуль:
# импортируем библиотеку
import urllib
# используем ее
urllib.urlopen(...)
Мы можем узнать, какие функции реализованы в каждом модуле, используя функцию dir
:
>>> import urllib
>>> dir(urllib)
['ContentTooShortError', 'FancyURLopener', 'MAXFTPCACHE', 'URLopener', '__all__', '__builtins__',
'__doc__', '__file__', '__name__', '__package__', '__version__', '_ftperrors', '_get_proxies',
'_get_proxy_settings', '_have_ssl', '_hexdig', '_hextochr', '_hostprog', '_is_unicode', '_localhost',
'_noheaders', '_nportprog', '_passwdprog', '_portprog', '_queryprog', '_safe_map', '_safe_quoters',
'_tagprog', '_thishost', '_typeprog', '_urlopener', '_userprog', '_valueprog', 'addbase', 'addclosehook',
'addinfo', 'addinfourl', 'always_safe', 'basejoin', 'c', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies',
'getproxies_environment', 'getproxies_macosx_sysconf', 'i', 'localhost', 'main', 'noheaders', 'os',
'pathname2url', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_macosx_sysconf', 'quote',
'quote_plus', 'reporthook', 'socket', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport',
'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'string', 'sys', 'test', 'test1',
'thishost', 'time', 'toBytes', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode',
'urlopen', 'urlretrieve']
Когда мы находим функцию в модуле, которую хотим использовать, мы можем прочитать о ней больше с помощью функции help
, используя интерпретатор Python:
help(urllib.urlopen)
Writing packages
Пакеты — это пространства имен, содержащие несколько пакетов и модулей. Это просто каталоги, но с определенными требованиями.
Каждый пакет в Python — это каталог, который ДОЛЖЕН содержать специальный файл под названием __init__.py
. Этот файл, который может быть пустым, указывает, что каталог, в котором он находится, является пакетом Python. Таким образом его можно импортировать так же, как модуль.
Если мы создадим каталог с именем foo
, который обозначает имя пакета, то мы можем создать модуль внутри этого пакета под названием bar
. Затем мы добавляем файл __init__.py
в каталог foo
.
Чтобы использовать модуль bar
, мы можем импортировать его двумя способами:
import foo.bar
или:
from foo import bar
В первом примере выше нам нужно использовать префикс foo
всякий раз, когда мы обращаемся к модулю bar
. Во втором примере это не нужно, потому что мы импортировали модуль в пространство имен нашего модуля.
Файл __init__.py
также может решать, какие модули пакет экспортирует в качестве API, оставляя другие модули внутренними, переопределяя переменную __all__
, как показано ниже:
__init__.py:
__all__ = ["bar"]
Упражнение
В этом упражнении выведите в алфавитном порядке список всех функций в модуле re
, содержащих слово find
.
import re
# Your code goes here
find_members = []
import re
# Your code goes here
find_members = []
for member in dir(re):
if "find" in member:
find_members.append(member)
print(sorted(find_members))
test_object('find_members')
success_msg('Great work!')
This site is generously supported by DataCamp. DataCamp offers online interactive Python Tutorials for Data Science. Join over a million other learners and get started learning Python for data science today!