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

411 строки
17 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 установила актуальный рабочий каталог, а затем в нём создала рабочий протокол.
```py
>>> import os
>>> os.chdir("C:\\Users\\Дружок\\Desktop\\ПОАС\\python-labs\\TEMA8")
>>> os.getcwd()
'C:\\Users\\Дружок\\Desktop\\ПОАС\\python-labs\\TEMA8'
```
## 2. Создание и использование модулей в среде Python.
Модулем в среде Python называется любая часть программного кода на этом языке, записанная в отдельном файле. В языке Python модули также являются объектами класса module.
Для дальнейшей работы с многомодульными программами были подключены ещё два важных модуля: sys и importlib.
```py
>>> import sys, importlib
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'importlib', 'os', 'sys']
```
### 2.1. Запуск модуля на выполнение через import.
С помощью текстового редактора оболочки IDLE в текущем рабочем каталоге был создан файл Mod1.py, содержимое которого представлено ниже.
```py
perm1=input('Mod1:Введите значение = ')
print('Mod1:Значение perm1=',perm1)
```
Созданный модуль был запущен с помощью инструкции 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\\Дружок\\Desktop\\ПОАС\\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', '_compat_pickle', ..., 'zipimport', 'zlib']
```
Для обеспечения возможности повторного импорта модуля, его нужно удалить из словаря с помощью метода pop():
```py
>>> sys.modules.pop("Mod1")
<module 'Mod1' from 'C:\\Users\\Дружок\\Desktop\\ПОАС\\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: Введите значение = 12
Mod1: Значение perm1 = 12
>>> sys.modules.pop("Mod1")
<module 'Mod1' from 'C:\\Users\\Дружок\\Desktop\\ПОАС\\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 …
В одном модуле может содержаться несколько программных единиц, поэтому иногда бывает целесообразней осуществлять не импорт модуля целиком, а только некоторой его части. Это можно сделать с помощью следующей конструкции:
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:
```py
def alpha():
print('****ALPHA****')
t=input('Значение t=')
return t
def beta(q):
import math
expi=q*math.pi
return math.exp(expi)
```
С помощью изученного метода импортирования частей модуля, была импортирована функция 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
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'al', 'bt', 'g', 'importlib', 'os', 'perm1', 'sys']
>>> 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.
```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)
```
Теперь программа состоит из нескольких модулей, которые работают вместе:
```py
>>> sys.modules.pop("Mod1")
<module 'Mod1' from 'C:\\Users\\Дружок\\Desktop\\ПОАС\\python-labs\\TEMA8\\Mod1.py'>
>>> sys.modules.pop("Mod2")
<module 'Mod2' from 'C:\\Users\\Дружок\\Desktop\\ПОАС\\python-labs\\TEMA8\\Mod2.py'>
>>> import Mod0
Mod1:Введите значение = 10
Mod1:Значение perm1= 10
perm1= 10
****ALPHA****
Значение t=10
tt= 10
qq= 44031505860631.98
>>> Mod0.tt; Mod0.qq; Mod0.Mod1.perm1
'10'
44031505860631.98
'10'
```
### 3.2. Создание многомодульной программы на примере функций из Темы 7.
Еще одним примером многомодульной программы может послужить реализованная в Теме 7 модель системы, состоящей из реального двигателя, тахогенератора и звена типа "Зона нечувствительности".
Все функции, описывающие работу устройств определены в модуль MM1.py:
```py
def realdvig(xtt, kk1, TT, yti1, ytin1):
# Модель реального двигателя
yp = kk1 \* xtt # Усилитель
yti1 = yp + yti1 # Усилитель
ytin1 = (yti1 + TT \* ytin1) / (TT + 1)
return \[yti1, ytin1]
def tahogen(xtt, kk2, yti2):
# Модель тахогенератора
yp = kk2 * xtt # Усилитель
yti2 = yp + yti2 # Интегратор
return yti2
def nechus(xtt, gran):
# Зона нечувствительности
if xtt < gran and xtt > (-gran):
return 0
elif xtt >= gran:
return xtt - gran
elif xtt <= (-gran):
return xtt + gran
```
Функции, обеспечивающие ввод параметров, формироване входного сигнала и реализацию модели расчета выходного сигнала, записаны в модуль MM2.py:
```py
znach = input("k1, T, k2, Xm, A, F, N = ").split(",")
k1 = float(znach[0])
T = float(znach[1])
k2 = float(znach[2])
Xm = float(znach[3])
A = float(znach[4])
F = float(znach[5])
N = int(znach[6])
import math
vhod = []
for i in range(N):
vhod.append(A * math.sin((2 * i * math.pi) / F))
import MM1 as mod
yi1 = 0; yin1 = 0; yi2 = 0
vyhod = []
for xt in vhod:
xt1 = xt - yi2
[yi1, yin1] = mod.realdvig(xt1, k1, T, yi1, yin1)
yi2 = mod.tahogen(yin1, k2, yi2)
yt = mod.nechus(yin1, Xm)
vyhod.append(yt)
```
Наконец, главная программа, запускающая на выполнение остальные модули и выводящая полученный результат, записана в модуль MM0.py:
```py
import MM2
print("y =", MM2.vyhod)
```
Пример работы такой многомодульной программы:
```py
>>> import MM0
k1, T, k2, Xm, A, F, N = 8, 5, 3, 5, 3, 50, 20
y = [0, 0, 0, 0, 0, 0, -0.5901518991576866, 3.452634704774537, 0.3642909010247486, -28.2151620053697, 26.675026712827304, 51.21473287127543, -172.66693667770392, 78.76799406127618, 417.8318242176528, -859.8658159198188, -43.91966881153879, 2710.4996464065, -3753.6472426408995, -2892.354195893288]
```
### 3.3. Области действия объектов в модулях.
Объекты в модулях обладают определенными зонами действия, что будет рассматриваться в последующих примерах.
Пример 1:
Обращение изнутри одной функции к другой в рамках одного модуля:
```py
# Модуль Mod2
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
# Модуль Mod2
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\\Дружок\\Desktop\\ПОАС\\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\\Дружок\\Desktop\\ПОАС\\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.