Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

393 строки
16 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Отчет по теме 8
Степанов Артём, А-02-23
## Модули и структурирование программы
### 1. Установка рабочего каталога. Создание рабочего протокола.
В оболочке IDLE установил актуальный рабочий каталог, а затем в нём создал рабочий протокол.
![Скриншот созданного рабочего протокола](pictures/figure0.png)
### 2. Создание и использование модулей в среде Python.
Модулем в среде Python называется любая часть программного кода на этом языке, записанная в отдельном файле. В языке Python модули также являются объектами класса module.
Для дальнейшей работы с многомодульными программами были подключены ещё два важных модуля: sys и importlib. Также была проверена корректность установки рабочего каталога.
```py
>>> import sys, importlib
>>> os.getcwd()
'C:\\Users\\User\\Desktop\\StepanovAV\\python-labs\\TEMA8'
```
#### 2.1. Запуск модуля на выполнение через __import__.
С помощью текстового редактора оболочки __IDLE__ в текущем рабочем каталоге был создан файл __Mod1.py__, содержимое которого представлено ниже.
![Скриншот содержимого файла Mod1.py](pictures/figure1.png)
Созданный модуль был запущен с помощью инструкции __import__:
```py
>>> import Mod1
Mod1: Введите значение = 5
Mod1: Значение perm1 = 5
>>> type(Mod1) # Определение класса модуля
<class 'module'>
>>> dir(Mod1) # Получение списка атрибутов модуля
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'perm1']
>>> Mod1.perm1 # Обращение к переменной perm из модуля Mod1
'5'
```
Повторный запуск модуля с помощью __import__ не происходит, однако при использовании функции __reload__ из импортированного ранее модуля __importlib__ всё работает как надо:
```py
>>> import Mod1 # Ничего не происходит
>>> importlib.reload(Mod1)
Mod1: Введите значение = 3
Mod1: Значение perm1 = 3
<module 'Mod1' from 'C:\\Users\\User\\Desktop\\StepanovAV\\python-labs\\TEMA8\\Mod1.py'>
>>> Mod1.perm1
'3'
```
#### 2.2. Обнаружение импортированных модулей.
Импортированные модули заносятся в словарь - значение атрибута __sys.modules__, поэтому их можно увидеть с помощью инструкции __keys()__.
```py
>>> print(sorted(sys.modules.keys()))
['Mod1', '__future__', '__main__', '_abc', '_ast', '_bisect', '_bz2', '_codecs', '_collections', '_collections_abc', ...., 'xml.parsers.expat.errors', 'xml.parsers.expat.model', 'zipimport', 'zlib']
```
Для обеспечения возможности повторного импорта модуля, его нужно удалить из словаря с помощью метода __pop()__:
```py
>>> sys.modules.pop("Mod1")
<module 'Mod1' from 'C:\\Users\\User\\Desktop\\StepanovAV\\python-labs\\TEMA8\\Mod1.py'>
>>> print(sorted(sys.modules.keys()))
['__future__', '__main__', '_abc', '_ast', '_bisect', '_bz2', '_codecs', '_collections', '_collections_abc', ...., 'xml.parsers.expat.errors', 'xml.parsers.expat.model', 'zipimport', 'zlib']
>>> import Mod1
Mod1: Введите значение = 123
Mod1: Значение perm1 = 123
>>> sys.modules.pop("Mod1")
<module 'Mod1' from 'C:\\Users\\User\\Desktop\\StepanovAV\\python-labs\\TEMA8\\Mod1.py'>
```
#### 2.3. Запуск модуля на выполнение с помощью __exec()__.
Запуск модуля на выполнение может проводиться и с помощью инструкции __exec()__, однако объект-модуль при этом не создается, а всё созданные при выполнении модуля объекты становятся объектами главной программы.
```py
>>> exec(open("Mod1.py").read())
Mod1: РведиСРµ Р·РЅР°Сение = 123 # Кодировка по умолчанию не совпала с нужной
Mod1: РРЅР°Сение perm1 = 123
>>> exec(open("Mod1.py", encoding = "utf-8").read()) # Установлена нужная кодировка
Mod1: Введите значение = 123
Mod1: Значение perm1 = 123
>>> perm1
'123'
>>> exec(open("Mod1.py", encoding = "utf-8").read())
Mod1: Введите значение = 999
Mod1: Значение perm1 = 999
>>> perm1
'999'
>>> exec(open("Mod1.py", encoding = "utf-8").read())
Mod1: Введите значение = 0
Mod1: Значение perm1 = 0
>>> perm1
'0'
```
#### 2.4. Использование инструкции __from ... import ...__.
В одном модуле может содержаться несколько программных единиц, поэтому иногда бывает целесообразней осуществлять не импорт модуля целиком, а только некоторой его части. Это можно сделать с помощью следующей конструкции: <br>
__from <Имя модуля> import <Имя объектов для импорта>__
```py
>>> from Mod1 import perm1
Mod1: Введите значение = 123
Mod1: Значение perm1 = 123
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '__warningregistry__', 'importlib', 'os', 'perm1', 'sys']
>>> "Mod1" in dir() # Модуль Mod1 не появился в памяти
False
>>> perm1 # Переменная модуля стала переменной главной программы с введенным значением
'123'
```
Был создан еще один модуль __Mod2.py__:
![Скриншот содержимого файла Mod2.py](pictures/figure2.png)
С помощью изученного метода импортирования частей модуля, была импортирована функция __beta__ модуля __Mod2.py__, а затем проверено её наличие и наличие самого модуля в памяти.
```py
>>> from Mod2 import beta
>>> g = beta(2)
****BETA****
>>> g
535.4916555247646
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '__warningregistry__', 'beta', 'g', 'importlib', 'os', 'perm1', 'sys']
>>> "Mod2" in dir()
False
>>> alpha() # Функция alpha не была импортировна, поэтому к ней нельзя обращаться
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
alpha()
NameError: name 'alpha' is not defined
```
Импортировать части модуля можно с заданными им псевдонимами, по которым можно в дальнейшем к ним обращаться:
```py
>>> from Mod2 import alpha as al
>>> al()
****ALPHA****
Значение t = 10
'10'
>>> del al, beta
>>> from Mod2 import alpha as al, beta as bt
>>> del al, bt
>>> from Mod2 import *
>>> tt = alpha()
****ALPHA****
Значение t = 0.12
>>> uu = beta(float(tt))
****BETA****
>>> uu
1.4578913609506803
```
### 3. Создание многомодульных программ.
#### 3.1. Пример простой многомодульной программы.
Создан еще один модуль __Mod0.py__, содержащий программу, вызывающую ранее созданные модули __Mod1.py__ и __Mod2.py__.
![Скриншот содержимого файла Mod0.py](pictures/figure3.png)
Теперь программа состоит из нескольких модулей, которые работают вместе:
```py
>>> sys.modules.pop("Mod1")
<module 'Mod1' from 'C:\\Users\\User\\Desktop\\StepanovAV\\python-labs\\TEMA8\\Mod1.py'>
>>> sys.modules.pop("Mod2")
<module 'Mod2' from 'C:\\Users\\User\\Desktop\\StepanovAV\\python-labs\\TEMA8\\Mod2.py'>
>>> import Mod0
Mod1: Введите значение = 10
Mod1: Значение perm1 = 10
perm1 = 10
****ALPHA****
Значение t = 3
tt = 3
****BETA****
qq = 12391.647807916694
>>> Mod0.tt; Mod0.qq; Mod0.Mod1.perm1
'3'
12391.647807916694
'10'
```
#### 3.2. Создание многомодульной программы на примере функций из Темы 7.
Еще одним примером многомодульной программы может послужить реализованная в Теме 7 модель системы, состоящей из реального двигателя, тахогенератора и звена типа "Зона нечувствительности".
Все функции, описывающие работу устройств определены в модуль __MM1.py__:
![Скриншот содержимого файла MM1.py](pictures/figure4.png)
Функции, обеспечивающие ввод параметров, формироване входного сигнала и реализацию модели расчета выходного сигнала, записаны в модуль __MM2.py__:
![Скриншот содержимого файла MM2.py](pictures/figure5.png)
Наконец, главная программа, запускающая на выполнение остальные модули и выводящая полученный результат, записана в модуль __MM0.py__:
![Скриншот содержимого файла MM0.py](pictures/figure6.png)
Пример работы такой многомодульной программы:
```py
>>> import MM0
k1, T, k2, Xm, A, F, N = 7, 4, 2, 5, 2, 50, 20
y = [0, 0, 0, 0, 0, 0, 0, -0.39627662846883105, 0, 9.668724846977355, -0.07997484684431111, -32.77665514794543, 19.986985016935915, 89.15532350718266, -90.23155569994853, -219.90169916154008, 317.79686112689075, 503.3897757045461, -1014.3998793707813, -1058.8166331134794]
```
#### 3.3. Области действия объектов в модулях.
Объекты в модулях обладают определенными зонами действия, что будет рассматриваться в последующих примерах.
__Пример 1:__
Обращение изнутри одной функции к другой в рамках одного модуля:
```py
def alpha():
print("****ALPHA****")
print("Вызов функции beta из функции alpha:", beta(0))
t = input("Значение t = ")
return t
```
```py
>>> import Mod2
>>> Mod2.alpha()
****ALPHA****
****BETA****
Вызов функции beta из функции alpha: 1.0
Значение t = 123
'123'
```
Аналогичный пример для второй функции:
```py
def beta(q):
print("****BETA****")
print("Вызов функции alpha из функции beta:", alpha())
import math
expi = q * math.pi
return math.exp(expi)
```
```py
>>> import Mod2
>>> Mod2.beta(4)
****BETA****
****ALPHA****
Значение t = 5
Вызов функции alpha из функции beta: 5
286751.31313665316
```
__Пример 2:__
Отображение во внешнем модуле объектов внутреннего модуля:
```py
# Модуль Mod0
import Mod1
print("perm1 =", Mod1.perm1)
from Mod2 import alpha as al
tt = al()
print("tt =", tt)
from Mod2 import beta
qq = beta(float(tt))
print("qq =", qq)
print("t =", t)
print("expi =", expi)
```
```py
>>> import Mod0
Mod1: Введите значение = 1
Mod1: Значение perm1 = 1
perm1 = 1
****ALPHA****
Значение t = 2
tt = 2
****BETA****
qq = 535.4916555247646
Traceback (most recent call last):
File "<pyshell#106>", line 1, in <module>
import Mod0
File "C:\Users\User\Desktop\StepanovAV\python-labs\TEMA8\Mod0.py", line 10, in <module>
print("t =", t, " expi =", expi)
NameError: name 't' is not defined. Did you mean: 'tt'?
```
При закомментировании обращения к переменной __t__, всё равно будет ошибка, так как переменная __expi__ также определена в другом модуле и напрямую доступа к ней нет.
```py
>>> import Mod0
Mod1: Введите значение = 1
Mod1: Значение perm1 = 1
perm1 = 1
****ALPHA****
Значение t = 2
tt = 2
****BETA****
qq = 535.4916555247646
Traceback (most recent call last):
File "<pyshell#111>", line 1, in <module>
import Mod0
File "C:\Users\User\Desktop\StepanovAV\python-labs\TEMA8\Mod0.py", line 11, in <module>
print("expi =", expi)
NameError: name 'expi' is not defined
```
__Пример 3:__
Изменение значений объектов внутреннего модуля во внешнем модуле:
```py
# Модуль Mod0
import Mod1
print("perm1 =", Mod1.perm1)
from Mod2 import alpha as al
tt = al()
print("tt =", tt)
from Mod2 import beta
qq = beta(float(tt))
print("qq =", qq)
Mod1.perm1 *= 3
print("perm1 * 3 =", Mod1.perm1)
```
Данный код будет работать, так как обращение к перменной __perm1__ происходит не напрямую, а с указанием родительского модуля - __Mod1__.
```py
>>> import Mod0
Mod1: Введите значение = 1
Mod1: Значение perm1 = 1
perm1 = 1
****ALPHA****
Значение t = 2
tt = 2
****BETA****
qq = 535.4916555247646
perm1 * 3 = 111 #
```
__Пример 4:__
Изменение значений объектов модуля из командной строки:
```py
>>> import Mod0
Mod1: Введите значение = 3
Mod1: Значение perm1 = 3
perm1 = 3
****ALPHA****
Значение t = 2
tt = 2
****BETA****
qq = 535.4916555247646
>>> perm1 *= 2
Traceback (most recent call last):
File "<pyshell#121>", line 1, in <module>
perm1 *= 2
NameError: name 'perm1' is not defined
>>> tt *= 2
Traceback (most recent call last):
File "<pyshell#122>", line 1, in <module>
tt *= 2
NameError: name 'tt' is not defined
>>> qq *= 2
Traceback (most recent call last):
File "<pyshell#123>", line 1, in <module>
qq *= 2
NameError: name 'qq' is not defined
```
__Вывод:__
Как видно из вышеперечисленных примеров, объекты, входящие в определенный модуль, имеют локализацию именно в данном модуле и обращение к ним напрямую доступно только в рамках данного модуля. В остальных же случаях обращение к таким переменным осуществляется с явным указанием родительского модуля.
### 4. Завершение работы со средой.
Сохранил файлы отчета в своем рабочем каталоге и закончил сеанс работы с IDLE.