Рассмотрение любого языка полезно начинать с рассмотрения типов данных этого языка. В этом отношении язык Python уникален. Такой развитой системы встроенных в язык типов нет ни в каком другом языке программирования. Обычно встроенных типов немного, а остальные реализуются типами, определенными в сопровождающих библиотеках, либо определяются самим программистом. В Питоне наряду со встроенными типами программисту доступен широкий набор библиотечных типов, определенных в модулях Питона.
В тексте, который я пишу, программный код играет важное, если не определяющее значение. Все приводимые примеры - это фрагменты созданного проекта. Для этой лекции я создал в Visual Studio 2019 - проект на языке Python Lecture1.rar, в который включил три модуля с именами; AriphmeticType, LogicalType, TextType. Каждый модуль содержит набор тестовых функций, которые вызываются для исполнения. Коды этих функций и полученные результаты приводятся в тексте лекций.
Язык Python относится к языкам ООП (объектно-ориентированного программирования). Но применение средств ООП не является обязательным. Поэтому, чаще всего, объекты программы называются переменными.
В строго типизированных языках всякому действию над переменной с именем x предшествует объявление переменной x, содержащее описание ее типа. В языке Python идеология другая. Важной особенностью языка Python является полное отсутствие объявлений переменных. По сути переменных в классическом понимании нет. Есть имена и есть объекты, представляющие значение. Имена никогда не объявляются, не связываются с определенным типом. Имена - это ссылки (указатели) на объекты. Связывание имени и объекта происходит динамически в момент выполнения операции присваивания. С этого момента имя ссылается на объект, указанный в правой части оператора присваивания. Эта связь работает до очередного присваивания этому же имени другого объекта. Заметьте, имя - это ссылка, которая может быть связана с объектом любого типа. При связывании с объектом имя временно получает тип и значение объекта, с которым она связывается. Тип и значение имеет объект, но не имя.
В ходе выполнения одного метода, одного блока имя может связываться с объектами разных типов. Это непривычная интерпретация, характерная именно для языка Python, отличная от интерпретации имени и понятия переменной в строго типизированных языках программирования.
Такая свобода упрощает процесс написания кода, уменьшает его длину. Иногда такой подход относят к достоинствам языка. Для простых программ небольшого объема это утверждение справедливо. Для серьезных программ, разрабатываемых коллективом разработчиков, такая стратегия чревата ошибками, увеличивает сложность понимания кода. Использовать одно и тоже имя для разных сущностей одного блока без сомнения означает нарушение всех правил стиля качественного программирования, когда не длине кода, а его корректности, уделяется основное внимание.
С другой стороны, с одним и тем же объектом может быть одновременно связано несколько имен - псевдонимов. Это важная концепция ООП, поскольку при передаче "тяжелых" объектов из одной части программы в другую достаточно передавать ссылку, а не сам объект. Такой способ эффективен, но чреват ошибками, поскольку изменение объекта в одной части программы отражается на всех псевдонимах в других частях программы. Работа с псевдонимами требует аккуратного программирования.
Понятно, что для простых типов данных, задающих "легкие" объекты, такой способ работы не желателен. Поэтому в языке Python введено понятие неизменяемых типов, к которым относится арифметический тип и другие простые типы данных. Объекты неизменяемых типов могут иметь имена - псевдонимы. Но изменять значение объекта не разрешается. Всякий раз, когда нужно изменить значение объекта, связанного с именем x, в результате изменения создается новый объект, с которым и связывается имя x. Старый объект, с которым было связано имя x, не изменяется, и все прежние псевдонимы x остаются связанными со старым объектом.
В язык Python встроен достаточно полный набор арифметических типов, используемых в математике:
Начиная с версии 3.0, существует единственный целочисленный тип, представляющий практически полное множество целых чисел. Если значение числа относительно невелико, то число представлено 32-мя битами. Если значение выходит за рамки отведенной памяти, то автоматически происходит переход к длинной арифметике и возможное значение ограничивается лишь допустимой памятью.
Пример:
# Примеры работы с арифметическим типом данных
def test1():
x = 2 ** 100 # длинное целое
print(x, type(x))
test1()
Вот результаты:
Целочисленные константы, называемые также литералами, можно задавать в различных системах счисления. Вот примеры:
def test2():
#constants
c1 = 111 #константа в десятичной системе счисления
c2 = 0b111 #константа в двоичной системе счисления
c3 = 0o111 #константа в восьмеричной системе счисления
c4 = 0x111 #константа в шестнадцатеричной системе счисления
c5 = int("111", 3) #константа в троичной системе счисления
print(c1, c2, c3, c4, c5)
test2()
Результаты работы:
Арифметические операции над целыми:
Примеры:
def test3():
#операции над целыми
x1 = 13 + 5; x2 = 13 - 5; print (x1, x2)
x1 = 13 * 5; x2 = 13 / 5; print (x1, x2)
x1 = 13 // 5; x2 = 13 % 5; print (x1, x2)
test3()
Результаты работы:
Импорт модуля math позволяет при работе с арифметическими данными вызывать различные функции, определенные в этом модуле, - тригонометрические, логарифмические, степенные и другие.
Примеры:
def test4():
#функции класса Math
import math
x1 = math.sin(math.radians(30)) + math.cos(math.radians(30));
print(x1, type(x1))
x2 = math.sqrt(20) + math.pow(20, 1/3)
print(x2, type(x2))
test4()
Результаты работы:
Над данными арифметического типа определены операции сравнения: >, <, >=, <=, ==, !=.
Результат этих операций принадлежит логическому типу bool.
Функция str позволяет привести арифметический тип к строковому.
Пример:
def test5():
# Операции сравнения и приведение арифметики к строковому типу
x = 8; y = 5; print("x = " + str(x) + " y = " + str(y))
if x > y: z = x
else: z = y
print("z = max(x,y) = " + str(z))
test5()
Результат работы:
Существует только один вещественный тип - float. Точность представления данных этого типа ограничена. Вещественное число содержит максимум 16 значащих цифр.
Константа вещественного типа содержит целую и дробную часть, с точкой в качестве разделителя. Константа также может содержать десятичный порядок. Целая часть константы может отсутствовать.
Пример:
def test6():
#Вещественные числа
x = 2.5 ** 200
print(x)
#Константы
x = -25.46e10; y = 25.46e-2; z = .5
print(x, y, z)
test6()
Результат работы:
Все операции и функции, рассмотренные в разделе "целые числа", применимы и к вещественным числам. Заметьте, операции деления нацело и взятие остатка от деления нацело применимы и к вещественным числам. При делении нацело дробная часть числа отрезается.
Пример:
def test7():
#деление нацело и остаток от деления нацело для чисел типа float
x = 13.5 // 2; y = 13.5 % 2
print("x = 13.5 // 2 = " + str(x) + " y = 13.5 % 2; = " + str(y))
test7()
Результат работы:
У вещественных чисел есть особенность, они представляют значение с некоторой погрешностью. Поэтому их нельзя сравнивать на точное равенство, а сравнение на "больше" и "меньше" справедливо лишь с точностью до малого значения эпсилон.
В финансовых вычислениях и некоторых других ситуациях необходимо избегать погрешностей, связанных с представлением вещественных чисел. В таких ситуациях используется тип Decimal. Тип определен в модуле decimal и должен быть импортирован до его использования.
Вот пример:
def test8():
from decimal import Decimal
x = Decimal('500000.125125'); y = Decimal('500000.125125');
z = x * y;
print(x, y, z, type(z))
# сравнение с float
x = 500000.125125; y = 500000.125125
z = x * y;
print(x, y, z, type(z))
test8()
Результат работы:
Результаты показывают, что умножение чисел Decimal дает точный результат, содержащий 24 значащие цифры. Аналогичное умножение чисел типа float сохраняет лишь 16 значащих цифр.
Над переменными типа Decimal определены все операции, введенные при описании целых чисел, в том числе операции деления нацело и остаток от деления нацело. Следует заметить, хотя точность представления чисел этого типа превосходит точность представления чисел типа float, но и она ограничена, числа этого типа содержат максимум 28 значащих цифр. Методы, представленные в модуле math применимы и к данным типа Decimal.
Для специфических задач, требующих повышенной точности представления данных использование типа Decimal представляется полезным.
Рациональные числа определены в модуле fractions и задаются парой числитель и знаменатель.
Пример:
def test9():
from fractions import Fraction
x = Fraction(4,5) + Fraction(3,8) - Fraction(8,10)
y = Fraction(4,2) * Fraction(8,8) / Fraction(88,11)
print(x, y, type(y))
test9()
Результаты:
Над переменными рационального типа Fraction определены все операции, введенные при описании целых чисел, в том числе операции деления нацело и остаток от деления нацело. Методы, представленные в модуле math применимы и к данным типа Fraction.
Заметьте, число 1/3, представленное типом float или Decimal, будет задано с определенной погрешностью. Тип Rational дает точное представление для чисел, которые в позиционной системе счисления представляют бесконечную периодическую дробь. Для специфических задач, требующих повышенной точности представления данных, использование типа Fraction представляется полезным.
Тип комплексных чисел встроен в язык. Числа задаются стандартным образом. Представление включает вещественную и мнимую часть. В качестве мнимой единицы используется имя j вместо стандартного для математики имени i.
Пример:
def test10():
#complex numbers
z1 = 2 + 5j; z2 = 3 - 4j
z3 = z1 + z2; z4 = z1 * z2; z5 = z1 / z2; z6 =z1 ** 2
print(z3, z4, z5, z6)
#z7 = z1 // 2; z8 = z1 % 2; операции не определены для типа complex
test10()
Результаты:
Набор арифметических операций над комплексными числами ограничен в сравнении с другими числовыми типами. Такие операции как деление нацело или взятие остатка для комплексных чисел не определены. Эти числа не могут выступать в качестве аргументов для методов модуля math. Не определены и операции сравнения на "больше", "меньше".
Для переменных этого типа определены операции, позволяющие получить действительную и мнимую часть числа, построить комплексно-сопряженное число, получающееся из исходного числа заменой знака мнимой части.
Операция сложения "+ ", как и другие арифметические операции, определена для разных подтипов арифметического типа. В этом случае говорят, что операция перегружена. Сложение целых - это одна операция, а сложение вещественных чисел или комплексных чисел совсем другая операция. Когда оба операнда операции сложения одного типа, то в зависимости от типов операндов выполняется операция сложения операндов этого типа.
Что происходит, когда необходимо выполнить операцию сложения над операндами, принадлежащих разным подтипам арифметического типа? Операции сложения для таких ситуаций не определены, тем не менее во многих случаях операции выполняются за счет правил неявного преобразования операндов, - один из операндов типа Т преобразуется и получает тип второго операнда типа T1. Неявное преобразование возможно только тогда, когда множество возможных значений типа T содержится в множестве возможных значений типа T1. В этом случае неявное преобразование всегда возможно и при преобразовании не происходит потеря точности. При неявном преобразовании простой тип приводится к более сложному типу. Операция выполняется над операндами одного типа (сложного типа) и результат операции определяется этим типом.
Возможны следующие цепочки неявных преобразований подтипов внутри арифметического типа:
int => Decimal int => Fraction => float => Complex
Заметьте, тип Decimal не приводится к другим типам.
Примеры:
def test11():
from decimal import Decimal
from fractions import Fraction
#implicit transformation of types
#x = Decimal('5.5') + Fraction(5,8) преобразование типов не поддерживается
#x = Decimal('5.5') + 5.8 преобразование типов не поддерживается
x = 5 + Decimal('5.5')
print(x, type(x))
x = 5 + 5.5 + Fraction(5,5)
print(x, type(x))
x = 5 + Fraction(5,5) + 5.5 + (5 + 5j)
print(x, type(x))
test11()
Результаты:
Рассмотрение любого языка полезно начинать с рассмотрения типов данных этого языка. В этом отношении язык Python уникален. Такой развитой системы встроенных в язык типов нет ни в каком другом языке программирования. Обычно встроенных типов немного, а остальные реализуются типами, определенными в сопровождающих библиотеках, либо определяются самим программистом. В Питоне наряду со встроенными типами программисту доступен широкий набор библиотечных типов, определенных в модулях Питона.
В тексте, который я пишу, программный код играет важное, если не определяющее значение. Все приводимые примеры - это фрагменты созданного проекта. Для этой лекции я создал в Visual Studio 2019 - проект на языке Python Lecture1.rar, в который включил три модуля с именами; AriphmeticType, LogicalType, TextType. Каждый модуль содержит набор тестовых функций, которые вызываются для исполнения. Коды этих функций и полученные результаты приводятся в тексте лекций.
Язык Python относится к языкам ООП (объектно-ориентированного программирования). Но применение средств ООП не является обязательным. Поэтому, чаще всего, объекты программы называются переменными.
В строго типизированных языках всякому действию над переменной с именем x предшествует объявление переменной x, содержащее описание ее типа. В языке Python идеология другая. Важной особенностью языка Python является полное отсутствие объявлений переменных. По сути переменных в классическом понимании нет. Есть имена и есть объекты, представляющие значение. Имена никогда не объявляются, не связываются с определенным типом. Имена - это ссылки (указатели) на объекты. Связывание имени и объекта происходит динамически в момент выполнения операции присваивания. С этого момента имя ссылается на объект, указанный в правой части оператора присваивания. Эта связь работает до очередного присваивания этому же имени другого объекта. Заметьте, имя - это ссылка, которая может быть связана с объектом любого типа. При связывании с объектом имя временно получает тип и значение объекта, с которым она связывается. Тип и значение имеет объект, но не имя.
В ходе выполнения одного метода, одного блока имя может связываться с объектами разных типов. Это непривычная интерпретация, характерная именно для языка Python, отличная от интерпретации имени и понятия переменной в строго типизированных языках программирования.
Такая свобода упрощает процесс написания кода, уменьшает его длину. Иногда такой подход относят к достоинствам языка. Для простых программ небольшого объема это утверждение справедливо. Для серьезных программ, разрабатываемых коллективом разработчиков, такая стратегия чревата ошибками, увеличивает сложность понимания кода. Использовать одно и тоже имя для разных сущностей одного блока без сомнения означает нарушение всех правил стиля качественного программирования, когда не длине кода, а его корректности, уделяется основное внимание.
С другой стороны, с одним и тем же объектом может быть одновременно связано несколько имен - псевдонимов. Это важная концепция ООП, поскольку при передаче "тяжелых" объектов из одной части программы в другую достаточно передавать ссылку, а не сам объект. Такой способ эффективен, но чреват ошибками, поскольку изменение объекта в одной части программы отражается на всех псевдонимах в других частях программы. Работа с псевдонимами требует аккуратного программирования.
Понятно, что для простых типов данных, задающих "легкие" объекты, такой способ работы не желателен. Поэтому в языке Python введено понятие неизменяемых типов, к которым относится арифметический тип и другие простые типы данных. Объекты неизменяемых типов могут иметь имена - псевдонимы. Но изменять значение объекта не разрешается. Всякий раз, когда нужно изменить значение объекта, связанного с именем x, в результате изменения создается новый объект, с которым и связывается имя x. Старый объект, с которым было связано имя x, не изменяется, и все прежние псевдонимы x остаются связанными со старым объектом.
В язык Python встроен достаточно полный набор арифметических типов, используемых в математике:
Начиная с версии 3.0, существует единственный целочисленный тип, представляющий практически полное множество целых чисел. Если значение числа относительно невелико, то число представлено 32-мя битами. Если значение выходит за рамки отведенной памяти, то автоматически происходит переход к длинной арифметике и возможное значение ограничивается лишь допустимой памятью.
Пример:
# Примеры работы с арифметическим типом данных
def test1():
x = 2 ** 100 # длинное целое
print(x, type(x))
test1()
Вот результаты:
Целочисленные константы, называемые также литералами, можно задавать в различных системах счисления. Вот примеры:
def test2():
#constants
c1 = 111 #константа в десятичной системе счисления
c2 = 0b111 #константа в двоичной системе счисления
c3 = 0o111 #константа в восьмеричной системе счисления
c4 = 0x111 #константа в шестнадцатеричной системе счисления
c5 = int("111", 3) #константа в троичной системе счисления
print(c1, c2, c3, c4, c5)
test2()
Результаты работы:
Арифметические операции над целыми:
Примеры:
def test3():
#операции над целыми
x1 = 13 + 5; x2 = 13 - 5; print (x1, x2)
x1 = 13 * 5; x2 = 13 / 5; print (x1, x2)
x1 = 13 // 5; x2 = 13 % 5; print (x1, x2)
test3()
Результаты работы:
Импорт модуля math позволяет при работе с арифметическими данными вызывать различные функции, определенные в этом модуле, - тригонометрические, логарифмические, степенные и другие.
Примеры:
def test4():
#функции класса Math
import math
x1 = math.sin(math.radians(30)) + math.cos(math.radians(30));
print(x1, type(x1))
x2 = math.sqrt(20) + math.pow(20, 1/3)
print(x2, type(x2))
test4()
Результаты работы:
Над данными арифметического типа определены операции сравнения: >, <, >=, <=, ==, !=.
Результат этих операций принадлежит логическому типу bool.
Функция str позволяет привести арифметический тип к строковому.
Пример:
def test5():
# Операции сравнения и приведение арифметики к строковому типу
x = 8; y = 5; print("x = " + str(x) + " y = " + str(y))
if x > y: z = x
else: z = y
print("z = max(x,y) = " + str(z))
test5()
Результат работы:
Существует только один вещественный тип - float. Точность представления данных этого типа ограничена. Вещественное число содержит максимум 16 значащих цифр.
Константа вещественного типа содержит целую и дробную часть, с точкой в качестве разделителя. Константа также может содержать десятичный порядок. Целая часть константы может отсутствовать.
Пример:
def test6():
#Вещественные числа
x = 2.5 ** 200
print(x)
#Константы
x = -25.46e10; y = 25.46e-2; z = .5
print(x, y, z)
test6()
Результат работы:
Все операции и функции, рассмотренные в разделе "целые числа", применимы и к вещественным числам. Заметьте, операции деления нацело и взятие остатка от деления нацело применимы и к вещественным числам. При делении нацело дробная часть числа отрезается.
Пример:
def test7():
#деление нацело и остаток от деления нацело для чисел типа float
x = 13.5 // 2; y = 13.5 % 2
print("x = 13.5 // 2 = " + str(x) + " y = 13.5 % 2; = " + str(y))
test7()
Результат работы:
У вещественных чисел есть особенность, они представляют значение с некоторой погрешностью. Поэтому их нельзя сравнивать на точное равенство, а сравнение на "больше" и "меньше" справедливо лишь с точностью до малого значения эпсилон.
В финансовых вычислениях и некоторых других ситуациях необходимо избегать погрешностей, связанных с представлением вещественных чисел. В таких ситуациях используется тип Decimal. Тип определен в модуле decimal и должен быть импортирован до его использования.
Вот пример:
def test8():
from decimal import Decimal
x = Decimal('500000.125125'); y = Decimal('500000.125125');
z = x * y;
print(x, y, z, type(z))
# сравнение с float
x = 500000.125125; y = 500000.125125
z = x * y;
print(x, y, z, type(z))
test8()
Результат работы:
Результаты показывают, что умножение чисел Decimal дает точный результат, содержащий 24 значащие цифры. Аналогичное умножение чисел типа float сохраняет лишь 16 значащих цифр.
Над переменными типа Decimal определены все операции, введенные при описании целых чисел, в том числе операции деления нацело и остаток от деления нацело. Следует заметить, хотя точность представления чисел этого типа превосходит точность представления чисел типа float, но и она ограничена, числа этого типа содержат максимум 28 значащих цифр. Методы, представленные в модуле math применимы и к данным типа Decimal.
Для специфических задач, требующих повышенной точности представления данных использование типа Decimal представляется полезным.
Рациональные числа определены в модуле fractions и задаются парой числитель и знаменатель.
Пример:
def test9():
from fractions import Fraction
x = Fraction(4,5) + Fraction(3,8) - Fraction(8,10)
y = Fraction(4,2) * Fraction(8,8) / Fraction(88,11)
print(x, y, type(y))
test9()
Результаты:
Над переменными рационального типа Fraction определены все операции, введенные при описании целых чисел, в том числе операции деления нацело и остаток от деления нацело. Методы, представленные в модуле math применимы и к данным типа Fraction.
Заметьте, число 1/3, представленное типом float или Decimal, будет задано с определенной погрешностью. Тип Rational дает точное представление для чисел, которые в позиционной системе счисления представляют бесконечную периодическую дробь. Для специфических задач, требующих повышенной точности представления данных, использование типа Fraction представляется полезным.
Тип комплексных чисел встроен в язык. Числа задаются стандартным образом. Представление включает вещественную и мнимую часть. В качестве мнимой единицы используется имя j вместо стандартного для математики имени i.
Пример:
def test10():
#complex numbers
z1 = 2 + 5j; z2 = 3 - 4j
z3 = z1 + z2; z4 = z1 * z2; z5 = z1 / z2; z6 =z1 ** 2
print(z3, z4, z5, z6)
#z7 = z1 // 2; z8 = z1 % 2; операции не определены для типа complex
test10()
Результаты:
Набор арифметических операций над комплексными числами ограничен в сравнении с другими числовыми типами. Такие операции как деление нацело или взятие остатка для комплексных чисел не определены. Эти числа не могут выступать в качестве аргументов для методов модуля math. Не определены и операции сравнения на "больше", "меньше".
Для переменных этого типа определены операции, позволяющие получить действительную и мнимую часть числа, построить комплексно-сопряженное число, получающееся из исходного числа заменой знака мнимой части.
Операция сложения "+ ", как и другие арифметические операции, определена для разных подтипов арифметического типа. В этом случае говорят, что операция перегружена. Сложение целых - это одна операция, а сложение вещественных чисел или комплексных чисел совсем другая операция. Когда оба операнда операции сложения одного типа, то в зависимости от типов операндов выполняется операция сложения операндов этого типа.
Что происходит, когда необходимо выполнить операцию сложения над операндами, принадлежащих разным подтипам арифметического типа? Операции сложения для таких ситуаций не определены, тем не менее во многих случаях операции выполняются за счет правил неявного преобразования операндов, - один из операндов типа Т преобразуется и получает тип второго операнда типа T1. Неявное преобразование возможно только тогда, когда множество возможных значений типа T содержится в множестве возможных значений типа T1. В этом случае неявное преобразование всегда возможно и при преобразовании не происходит потеря точности. При неявном преобразовании простой тип приводится к более сложному типу. Операция выполняется над операндами одного типа (сложного типа) и результат операции определяется этим типом.
Возможны следующие цепочки неявных преобразований подтипов внутри арифметического типа:
int => Decimal int => Fraction => float => Complex
Заметьте, тип Decimal не приводится к другим типам.
Примеры:
def test11():
from decimal import Decimal
from fractions import Fraction
#implicit transformation of types
#x = Decimal('5.5') + Fraction(5,8) преобразование типов не поддерживается
#x = Decimal('5.5') + 5.8 преобразование типов не поддерживается
x = 5 + Decimal('5.5')
print(x, type(x))
x = 5 + 5.5 + Fraction(5,5)
print(x, type(x))
x = 5 + Fraction(5,5) + 5.5 + (5 + 5j)
print(x, type(x))
test11()
Результаты:
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.