Єдина Країна!

Головне меню

Наша кнопка

Українські уроки про ІТ

Друзі

Підтримка української армії



Модулі в Python
Написав Invader   
Субота, 16 лютого 2013 14:52
Переглядів: 13830

Python ua:Модулі

Вступне слово

В попередніх уроках ти побачив, що достатньо оголосити функцію лише один раз і потім багаторазово використовувати код, який вона реалізує. Для того, щоб багаторазово використати один і той самий код можна оголосити функцію лише раз. Але що якщо ти хочеш використати певну к-ть функцій в інших своїх програмах? Як ти вже, мабуть здогадався, відповідь — модулі.

 

Існують різні методи написання модулів, але найпростіший шлях це створити файл з розширенням .py який містить функції і змінні.

Інший метод — написати модуль на рідній мові на якій написано і сам інтерпретатор Python. Наприклад, ти можеш писати модулі на мові програмування C (http://docs.python. org/extending/), і коли ці модулі будуть скомпільовані, то їх можна буде використовувати прямо із Python-програми.

Модуль може бути імпортований іншою програмою для того шоб використовувати його функції. Таким самим чином ми можем використовувати стандартну бібліотеку Python. Спершу розглянемо використання стандартної бібліотеки модулів.

Приклад:

#!/usr/bin/python
# Filename: using_sys.py

import sys

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

print('\n\nThe PYTHONPATH is', sys.path, '\n')


Виведе:

	
$ python using_sys.py ми аргументи
Аргументи командного рядка:
using_sys.py
ми
аргументи

The PYTHONPATH is ['', 'C:\\Windows\\system32\\python30.zip',
'C:\\Python30\\DLLs', 'C:\\Python30\\lib',
'C:\\Python30\\lib\\plat-win', 'C:\\Python30',
'C:\\Python30\\lib\\site-packages']

Як це працює:

Спершу ми імпортували модуль sys використовуючи оператор import. По суті ми кажемо Python що хочемо використовувати цей модуль. Модуль sys містить функціональність, яка стосується самого інтерпретатора і його оточення (системи, іншими словами).

Коли Python виконує код import sys, то він шукає модуль sys. У даному випадку, це один з вбудованих модулів, і тому Python знає де знайти його.

Якби це був не скомпільований модуль (модуль написаний на мові програмування Python), тоді б інтерпретатор Python шукав би його (модуль) в директоріях, що містяться в змінній sys.path. Якщо модуль знайдено, то інструкції в тілі модуля виконуються і потім модуль стає доступним для використання. Зауваж, що ініціалізація модуля відбувається тільки першого разу, коли ми імпортуємо модуль.

Для отримання доступу до змінної arg в модулі sys використовується крапкова нотація (dotted notation) — sys.argv. Таким чином стає цілком зрозуміло, що це ім’я (argv) є частиною модуля sys. Інша перевага полягає в тому, що ім’я не конфліктує із однойменною змінною в твоїй програмі.

Змінна sys.argv це — список рядків (поняття списків в Python буде пояснено більш детальніше в наступному розділі). Саме sys.argv містить список аргументів командного рядка (це аргументи які були передані програмі в командному рядку).

Якщо ти використовуєш IDE для написання і запуску цих програм, то пошукай спосіб вказати аргументи командного рядка для твоєї програми десь в меню.

Коли ми виконуємо "python using_sys.py ми аргументи", то ми запускаємо модуль using_sys.py за допомогою команди python, а все інше що йде в кінці — аргументи передані програмі. Python зберігає аргументи командного рядка в змінній sys.argv для того щоб ми могли їх використовувати.

Запам’ятай, що ім’я скрипта який в даний момент виконується це завжди перший аргумент у списку sys.argv. Отже, в цьому випадку 'using_sys.py' це sys.argv[0], 'ми' це sys.argv[1], 'аргументи' це sys.argv[2]. Зауваж що Python починає рахувати з 0, а не з 1.

sys.path містить список каталогів звідки були імпортовані модулі. Зауваж, що перший рядок в sys.path порожній — цей порожній рядок вказує на те, що поточний каталог також є частиною sys.path який, в свою чергу, є ідентичним до змінної середовища PYTHONPATH. Це означає що ти можеш напряму імпортувати модулі розташовані в поточному каталозі. В іншому випадку, ти будеш змушений помістити свій модуль в один з каталогів зі списку в sys.path.

Зауваж, що поточний каталог це каталог звідки було запущено програму. Запусти код import os; print(os.getcwd()) для того щоб з’ясувати потоний каталог твоєї програми.

Байт-компільовані .pyc файли

Імпорт модуля доволі накладна операція в плані ресурсів, тому Python йде на певні хитрощі для того, щоб зробити її швидшою. Один із шляхів це створення байт-компільованих файлів з розширенням .pyc (проміжна форма в яку інтерпретатор Python перетворює програму).

Цей .pyc файл виявляється дуже корисним коли ти імпортуєш цей же модуль з іншої програми — операція імпорту буде набагато швидшою оскільки частина операції по імпорту вже виконана. Також, ці файли є платформо-незалежними.

Зауваження

.pyc файли зазвичай створюються в тому ж каталозі що і відповідні файли .py. Якщо у Python немає достатніх прав на запис, тоді .pyc файли не будуть створені.

Інструкція from …import

Якщо ти хочеш напряму імпортувати змінну argv в свою програму (для того щоб уникнути друкування sys. кожного разу), то тоді ти можеш скористатися інструкцією from sys import argv. Для імпорту всіх імен з модуля sys треба написати from sys import *. Це працює для будь-якого модуля.

В цілому ти повинен уникати цієї інструкції і натомість використовувати оператор import, оскільки твоя програма уникне плутанини з іменами і буде більш читабельною.

Атрибут __name__ модуля

Кожен модуль має ім’я і код всередині цього модуля може з’ясувати назву свого модуля. Це виявляється зручним у тих ситуаціях, коли потрібно з’ясувати чи модуль викор. сам по собі чи його було імпортовано. Як вже було зауважено вище, коли модуль імпортується першого разу, код всередині нього виконується. Ми можемо скористатися цією концепцією для зміни поведінки модуля, якщо програма була виконана сама по собі (не імпортована, її запустив безпосередньо користувач), а не коли вона була імпортована з іншого модуля. Цього можна досягти використанням атрибуту __name__ модуля.

Приклад:

#!/usr/bin/python
# Filename: using_name.py

if __name__ == '__main__':
	print('This program is being run by itself')
else:
	print('I am being imported from another module')

Виведе:

	
$ python using_name.py
This program is being run by itself

$ python
>>> import using_name
I am being imported from another module
>>>
	

Як це працює:

Кожен Python-модуль має своє власне __ім’я__ (атрибут __name__). Якщо модуль було запущено безпосередньо користувачем (не імпортовано), то воно набуде значення '__name__'.

Створення власних модулів

Створення своїх власних модулів легке заняття, ти займався цим весь час. Це тому що кожна Python-програма це також і модуль. Тобі треба лише впевнитись, що файл має розширення py. Наступний приклад повинен зробити це зрозумілим.

Приклад:

#!/usr/bin/python
# Filename: mymodule.py

def sayhi():
	print('Hi, this is mymodule speaking.')
__version__ = '0.1'
#Кінець модуля mymodule.py

Код вище це приклад модуля. Як тим можеш бачити там немає нічого особливого в порівнянні зі звичайними Python-програмами. Далі ми побачимо як використати цей модуль в наших інших Python-програмах.

Запам’ятай, що модуль має розміщуватися в тому ж каталозі, що й програма в яку ми його імпортуємо, інакше (в протилежному випадку), модуль повинен бути в одному з каталогів перерахованих в sys.path.

#!/usr/bin/python
# Filename: mymodule_demo.py

import mymodule

mymodule.sayhi()
print ('Version', mymodule.__version__)

Виведе:

	
$ python mymodule_demo.py
Hi, this is mymodule speaking.
Version 0.1
	

Як це працює:

Зауваж що ми використали ту ж саму крапкову нотацію для доступу до членів модуля. Ось версія з використанням інструкції from…import:

#!/usr/bin/python
# Filename: mymodule_demo2.py

from mymodule import sayhi, __version__

sayhi()
print('Version', __version__)

Вивід програми mymodule_demo2.py такий самий як і програми mymodule_demo.py.

Зауваж, що якщо в модулі який імпортує mymodule вже існувало ім’я __version__, то виникне конфлікт. Це загальноприйнята практика оголошувати номер версії для кожного модуля за допомогою саме цієї змінної (__version__). Тому, краще завжди викор. інструкцію import навіть, якщо це може зробити твою програму трохи довшою.

Ти також можеш писати:

from mymodule import *

Цей код імпортує всі публічні імена, такі як sayhi, але не __version__ тому, що воно починається зі знаків нижнього підкреслювання.

Python`івський Дзен

Один із головних принципів Python — "Явне краще ніж неявне". Виконай команду import this в інтерпретаторі для того щоб дізнатися більше. Також переглянь це обговорення. Воно містить список прикладів який ілюструє кожен із цих принципів.

Функція dir

Ти можеш використовувати вбудовану функцію dir для отримання списку всіх ідентифікаторів визначених об’єктом. Наприклад, для модуля, цей список включає в себе функції, класи і змінні визначені в модулі.

Коли ти передаєш ім’я модуля як аргумент функції dir(), вона повертає список імен визначених всередині модуля. У випадку, коли функції не передано жодних аргументів вона повертає список імен визначених всередині поточного модуля.

Приклад:

$ python

>>> import sys # отримати список атрибутів, в цьому випадку, для модуля sys

>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__',
'__package__', '__s
tderr__', '__stdin__', '__stdout__', '_clear_type_cache',
'_compact_freelists',
'_current_frames', '_getframe', 'api_version', 'argv',
'builtin_module_names', '
byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook',
'dllhandle'
, 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
'executable',
'exit', 'flags', 'float_info', 'getcheckinterval',
'getdefaultencoding', 'getfil
esystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount',
'getsizeof',
'gettrace', 'getwindowsversion', 'hexversion', 'intern', 'maxsize',
'
maxunicode
', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',

'platfor
m', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile',
'setrecursionlimit
', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version',
'version_in
fo', 'warnoptions', 'winver']

>>> dir() # отримати список атрибутів поточного модуля
['__builtins__', '__doc__', '__name__', '__package__', 'sys']
>>> a = 5 # створити нову змінну 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'sys']
>>> del a # видалити/усунути ім’я
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys']
>>>

Як це працює:

Вперше ми використали функцію dir в імпортованому модулі sys. Ми можемо бачити величезний список атрибутів які містяться в ньому. Далі ми викликаємо функцію dir без аргументів. Типова поведінка функції в цьому випадку — повернути сисок атрибутів поточного модуля. Зауваж, що список імпортованих модулів також є частиною списку.

Для спостереження за dir в дії ми оголосили нову змінну a і присвоїли їй значення, потім, запустивши dir ще раз, ми переконалися, що було створено нове значення у списку атрибутів поточного модуля. Ми видалили атрибут скориставшись інструкцією del і переконалися в цьому ще раз викликавши функцію dir.

Зауваження щодо del — цей оператор використовується для видалення змінної/імені, і після виконання команди del a ти втратиш доступ до a. Так ніби її ніколи не існувало.

Зауваж, що функція dir() працює з будь-яким об’єктом. Наприклад, запусти dir(print) для того, щоб дізнатися про атрибути функції print, або dir(str) для отримання списку атрибутів класу str.

Пакети

До цього часу ви, мабуть, вже помітили ієрархію (структуру, загальні риси) побудови ваших програм.

Змінні зазвичай, йдуть всередині функцій. Функції і глобальні змінні зазвичай знаходяться всередині модулів. Що якщо ти хочеш організувати модулі? Ось де пакети приходять на допомогу.

Пакети — це просто директорії з модулями зі спеціальним файлом __init__.py всередині. Цей файл вказує Python на те що директорія є спеціальною оскільки вона включає модулі Python.

Скажімо, наприклад, ти хочеш створити пакет 'world' з субпакетами 'asia','africa', etc. І ці пакети, в свою чергу, теж містять інші модулі: 'india', 'madagascar', etc

Ось як би ти структурував директорії:

- /
	- world/
		- __init__.py
		- asia/
			- __init__.py
			- india/
				- __init__.py
				- foo.py
		- africa/
		- __init__.py
		- madagascar/
			- __init__.py
			- bar.py

Пакети — просто зручний спосіб ієрархічно організувати модулі. Ти побачиш приклади цього в стандартній бібліотеці.

Підсумок

Так само як функції це повторновикористовувані частини програми, модулі є повторновикористовуваними програмами. Пакети — інший рівень ієрархії для організації модулів. Стандартна бібліотека, яка постачається разом з Python є прикладом подібного набору пакетів і модулів.

Ми побачили як використовувати ці модулі і створювати власні.

Далі ми дізнаємося про деякі цікаві концепції, які називаються структурами даних.

 

Автор перекладу - Дмитро Юрченко


( 6 Проголосувало )
Коментарі
Добавити новий
Залишити коментар
Ім`я:
e-mail:
 
Тема:
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Введіть цей настирливий код
Русская редакция: www.freedom-ru.net & www.joobb.ru

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 

Підписка

Хто онлайн?

Немає
На даний момент 14 гостей на сайті

Український рейтинг
TOP.TOPUA.NET