ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
. Далее переменной help присваиваем число 10. После переопределения идентифика- тора мы больше не можем пользоваться функцией help() , т. к. это приведет к выводу сооб- щения об ошибке. По этой причине лучше избегать имен, совпадающих со встроенными идентификаторами. Очень часто подобная ошибка возникает при попытке назвать перемен- ную, в которой предполагается хранение строки, именем str . Вроде бы логично, но str является часто используемым встроенным идентификатором и после такого переопределения поведение программы становится непредсказуемым. В редакторе IDLE встроенные иденти- фикаторы подсвечиваются фиолетовым цветом. Обращайте внимание на цвет перемен- ной — он должен быть черным. Если вы заметили, что переменная подсвечена, то название переменной следует обязательно изменить. Получить полный список встроенных иденти- фикаторов позволяет следующий код: >>> import builtins >>> print(dir(builtins)) Правильные имена переменных: x , y1 , strName , str_name Неправильные имена переменных: 1y , ИмяПеременной Последнее имя неправильное, т. к. в нем используются русские буквы. Хотя на самом деле такой вариант также будет работать, но лучше русские буквы все же не применять: >>> ИмяПеременной = 10 # Лучше так не делать!!! >>> ИмяПеременной 10 При указании имени переменной важно учитывать регистр букв: x и X — разные перемен- ные: >>> x = 10; X = 20 >>> x, X (10, 20) 2.2. Типы данных В Python 3 объекты могут иметь следующие типы данных: bool — логический тип данных. Может содержать значения True или False , которые ведут себя как числа 1 и 0 соответственно: >>> type(True), type(False) ( >>> int(True), int(False) (1, 0) NoneType — объект со значением None (обозначает отсутствие значения): >>> type(None) 42 Часть I. Основы языка Python В логическом контексте значение None интерпретируется как False : >>> bool(None) False int — целые числа. Размер числа ограничен лишь объемом оперативной памяти: >>> type(2147483647), type(999999999999999999999999) ( float — вещественные числа: >>> type(5.1), type(8.5e-3) ( complex — комплексные числа: >>> type(2+2j) str — Unicode-строки: >>> type("Строка") bytes — неизменяемая последовательность байтов: >>> type(bytes("Строка", "utf-8")) bytearray — изменяемая последовательность байтов: >>> type(bytearray("Строка", "utf-8")) list — списки. Тип данных list аналогичен массивам в других языках программирова- ния: >>> type( [1, 2, 3] ) tuple — кортежи: >>> type( (1, 2, 3) ) range — диапазоны: >>> type( range(1, 10) ) dict — словари. Тип данных dict аналогичен ассоциативным массивам в других языках программирования: >>> type( {"x": 5, "y": 20} ) set — множества (коллекции уникальных объектов): >>> type( {"a", "b", "c"} ) Глава 2. Переменные 43 frozenset — неизменяемые множества: >>> type(frozenset(["a", "b", "c"])) ellipsis — обозначается в виде трех точек или слова Ellipsis . Тип ellipsis использу- ется в расширенном синтаксисе получения среза: >>> type(...), ..., ... is Ellipsis ( >>> class C(): def __getitem__(self, obj): return obj >>> c = C() >>> c[..., 1:5, 0:9:1, 0] (Ellipsis, slice(1, 5, None), slice(0, 9, 1), 0) function — функции: >>> def func(): pass >>> type(func) module — модули: >>> import sys >>> type(sys) type — классы и типы данных. Не удивляйтесь! Все данные в языке Python являются объектами, даже сами типы данных! >>> class C: pass >>> type(C) >>> type(type("")) Основные типы данных делятся на изменяемые и неизменяемые. К изменяемым типам относятся списки, словари и тип bytearray . Пример изменения элемента списка: >>> arr = [1, 2, 3] >>> arr[0] = 0 # Изменяем первый элемент списка >>> arr [0, 2, 3] К неизменяемым типам относятся числа, строки, кортежи, диапазоны и тип bytes . Напри- мер, чтобы получить строку из двух других строк, необходимо использовать операцию кон- катенации, а ссылку на новый объект присвоить переменной: >>> str1 = "авто" >>> str2 = "транспорт" >>> str3 = str1 + str2 # Конкатенация >>> print(str3) автотранспорт 44 Часть I. Основы языка Python Кроме того, типы данных делятся на последовательности и отображения. К последова- тельностям относятся строки, списки, кортежи, диапазоны, типы bytes и bytearray , а к ото- бражениям — словари. Последовательности и отображения поддерживают механизм итераторов, позволяющий произвести обход всех элементов с помощью метода __next__() или функции next() . На- пример, вывести элементы списка можно так: >>> arr = [1, 2] >>> i = iter(arr) >>> i.__next__() # Метод __next__() 1 >>> next(i) # Функция next() 2 Если используется словарь, то на каждой итерации возвращается ключ: >>> d = {"x": 1, "y": 2} >>> i = iter(d) >>> i.__next__() # Возвращается ключ 'y' >>> d[i.__next__()] # Получаем значение по ключу 1 На практике подобным способом не пользуются. Вместо него применяется цикл for , кото- рый использует механизм итераторов незаметно для нас. Например, вывести элементы спи- ска можно так: >>> for i in [1, 2]: print(i) Перебрать слово по буквам можно точно так же. Для примера вставим тире после каждой буквы: >>> for i in "Строка": print(i + " -", end=" ") Результат: С — т — р — о — к — а - Пример перебора элементов словаря: >>> d = {"x": 1, "y": 2} >>> for key in d: print( d[key] ) Последовательности поддерживают также обращение к элементу по индексу, получение среза, конкатенацию (оператор + ), повторение (оператор * ) и проверку на вхождение (опе- ратор in ). Все эти операции мы будем подробно рассматривать по мере изучения языка. 2.3. Присваивание значения переменным Присваивание — это занесение в переменную какого-либо значения (при этом значение, хранившееся в переменной ранее, теряется). Присваивание выполняется с помощью опера- тора = (знак равенства) таким образом: Глава 2. Переменные 45 >>> x = 7 # Тип int >>> y = 7.8 # Тип float >>> s1 = "Строка" # Переменной s1 присвоено значение Строка >>> s2 = 'Строка' # Переменной s2 также присвоено значение Строка >>> b = True # Переменной b присвоено логическое значение True В одной строке можно присвоить значение сразу нескольким переменным: >>> x = y = 10 # Переменным x и y присвоено число 10 >>> x, y (10, 10) После присваивания значения в переменной сохраняется ссылка на объект, а не сам объект. Это обязательно следует учитывать при групповом присваивании. Групповое присваивание можно использовать для чисел, строк и кортежей, но для изменяемых объектов этого делать нельзя. Пример: >>> x = y = [1, 2] # Якобы создали два объекта >>> x, y ([1, 2], [1, 2]) В этом примере мы создали список из двух элементов, присвоили его переменным x и y и теперь полагаем, что эти переменные хранят две разные копии упомянутого списка. Теперь попробуем изменить значение одного из элементов списка, что хранится в переменной y : >>> y[1] = 100 # Изменяем второй элемент списка >>> x, y ([1, 100], [1, 100]) Как видно из примера, изменение значения элемента списка из переменной y привело также к изменению значения того же элемента списка из переменной x . То есть, обе переменные ссылаются на один и тот же объект, а не на два разных объекта. Чтобы получить два объек- та, необходимо производить раздельное присваивание: >>> x = [1, 2] >>> y = [1, 2] >>> y[1] = 100 # Изменяем второй элемент >>> x, y ([1, 2], [1, 100]) Проверить, ссылаются ли две переменные на один и тот же объект, позволяет оператор is Если переменные ссылаются на один и тот же объект, оператор is возвращает значение True : >>> x = y = [1, 2] # Один объект >>> x is y True >>> x = [1, 2] # Разные объекты >>> y = [1, 2] # Разные объекты >>> x is y False Следует заметить, что в целях повышения эффективности кода интерпретатор производит кэширование малых целых чисел и небольших строк. Это означает, что если ста перемен- ным присвоено число 2, то, скорее всего, в этих переменных будет сохранена ссылка на один и тот же объект. Пример: 46 Часть I. Основы языка Python >>> x = 2; y = 2; z = 2 >>> x is y, y is z (True, True) Посмотреть количество ссылок на объект позволяет метод getrefcount() из модуля sys : >>> import sys # Подключаем модуль sys >>> sys.getrefcount(2) 304 Когда число ссылок на объект становится равно нулю, объект автоматически удаляется из оперативной памяти. Исключением являются объекты, которые подлежат кэшированию. Помимо группового, Python поддерживает позиционное присваивание. В этом случае пере- менные записываются через запятую слева от оператора = , а значения — через запятую справа. Пример позиционного присваивания: >>> x, y, z = 1, 2, 3 >>> x, y, z (1, 2, 3) С помощью позиционного присваивания можно поменять значения переменных местами. Пример: >>> x, y = 1, 2 >>> x, y (1, 2) >>> x, y = y, x >>> x, y (2, 1) По обе стороны оператора = могут быть указаны последовательности, к каковым относятся строки, списки, кортежи, диапазоны, типы bytes и bytearray : >>> x, y, z = "123" # Строка >>> x, y, z ('1', '2', '3') >>> x, y, z = [1, 2, 3] # Список >>> x, y, z (1, 2, 3) >>> x, y, z = (1, 2, 3) # Кортеж >>> x, y, z (1, 2, 3) >>> [x, y, z] = (1, 2, 3) # Список слева, кортеж справа >>> x, y, z (1, 2, 3) Обратите внимание на то, что количество элементов справа и слева от оператора = должно совпадать, иначе будет выведено сообщение об ошибке: >>> x, y, z = (1, 2, 3, 4) Traceback (most recent call last): File " ", line 1, in ValueError: too many values to unpack (expected 3) Глава 2. Переменные 47 Python 3 при несоответствии количества элементов справа и слева от оператора = позволяет сохранить в переменной список, состоящий из лишних элементов. Для этого перед именем переменной указывается звездочка ( * ): >>> x, y, *z = (1, 2, 3, 4) >>> x, y, z (1, 2, [3, 4]) >>> x, *y, z = (1, 2, 3, 4) >>> x, y, z (1, [2, 3], 4) >>> *x, y, z = (1, 2, 3, 4) >>> x, y, z ([1, 2], 3, 4) >>> x, y, *z = (1, 2, 3) >>> x, y, z (1, 2, [3]) >>> x, y, *z = (1, 2) >>> x, y, z (1, 2, []) Как видно из примера, переменная, перед которой указана звездочка, всегда получает в ка- честве значения список. Если для этой переменной не хватило значений, то ей присваивает- ся пустой список. Следует помнить, что звездочку можно указать только перед одной пере- менной, в противном случае возникнет неоднозначность и интерпретатор выведет сообще- ние об ошибке: >>> *x, y, *z = (1, 2, 3, 4) SyntaxError: two starred expressions in assignment 2.4. Проверка типа данных Во многих языках программирования при создании переменной нужно указывать тип дан- ных, к которому должны относиться значения, присваиваемые этой переменной. Но в Python этого делать не нужно, поскольку любая переменная может хранить значения любо- го типа. Выяснить тип данных, к которому относится хранящееся в переменной значение, позволяет функция type(<Имя переменной>) : >>> type(a) Проверить тип данных у значения, хранящегося в переменной, можно следующими спосо- бами: сравнить значение, возвращаемое функцией type() , с названием типа данных: >>> x = 10 >>> if type(x) == int: print("Это целое число (тип int)") проверить тип с помощью функции isinstance() : >>> s = "Строка" >>> if isinstance(s, str): print("Это строка (тип str)") 48 Часть I. Основы языка Python 2.5. Преобразование типов данных Над значением, относящимся к определенному типу, можно производить лишь операции, допустимые для этого типа данных. Например, можно складывать друг с другом числа, но строку сложить с числом нельзя — это приведет к выводу сообщения об ошибке: >>> 2 + "25" Traceback (most recent call last): File " ", line 1, in 2 + "25" TypeError: unsupported operand type(s) for +: 'int' and 'str' Для преобразования значения из одного типа данных в другой предназначены следующие функции: bool([<Объект>]) — преобразует объект в логический тип данных: >>> bool(0), bool(1), bool(""), bool("Строка"), bool([1, 2]), bool([]) (False, True, False, True, True, False) int([<Объект>[, <Система счисления>]]) — преобразует объект в число. Во втором па- раметре можно указать систему счисления (значение по умолчанию — 10). Примеры: >>> int(7.5), int("71") (7, 71) >>> int("71", 10), int("71", 8), int("0o71", 8), int("A", 16) (71, 57, 57, 10) Если преобразование невозможно, то генерируется исключение: >>> int("71s") Traceback (most recent call last): File " ", line 1, in ValueError: invalid literal for int() with base 10: '71s' float([<Число или строка>]) — преобразует целое число или строку в вещественное число: >>> float(7), float("7.1") (7.0, 7.1) >>> float("Infinity"), float("-inf") (inf, -inf) >>> float("Infinity") + float("-inf") nan str([<Объект>]) — преобразует объект в строку: >>> str(125), str([1, 2, 3]) ('125', '[1, 2, 3]') >>> str((1, 2, 3)), str({"x": 5, "y": 10}) ('(1, 2, 3)', "{'y': 10, 'x': 5}") >>> str(bytes("строка", "utf-8")) "b'\\xd1\\x81\\xd1\\x82\\xd1\\x80\\xd0\\xbe\\xd0\\xba\\xd0 \\xb0'" >>> str(bytearray("строка", "utf-8")) Глава 2. Переменные 49 "bytearray(b'\\xd1\\x81\\xd1\\x82\\xd1\\x80\\xd0\\xbe\\xd0 \\xba\\xd0\\xb0')" str(<Объект>[, <Кодировка>[, <Обработка ошибок>]]) — преобразует объект типа bytes или bytearray в строку. В третьем параметре можно задать значение "strict" (при ошибке возбуждается исключение UnicodeDecodeError — значение по умолчанию), "replace" (неизвестный символ заменяется символом, имеющим код \uFFFD ) или "ignore" (неизвестные символы игнорируются). Примеры: >>> obj1 = bytes("строка1", "utf-8") >>> obj2 = bytearray("строка2", "utf-8") >>> str(obj1, "utf-8"), str(obj2, "utf-8") ('строка1', 'строка2') >>> str(obj1, "ascii", "strict") Traceback (most recent call last): File " ", line 1, in UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 0: ordinal not in range(128) >>> str(obj1, "ascii", "ignore") '1' bytes(<Строка>, <Кодировка>[, <Обработка ошибок>]) — преобразует строку в объект типа bytes . В третьем параметре могут быть указаны значения "strict" (значение по умолчанию), "replace" или "ignore" . Примеры: >>> bytes("строка", "cp1251") b'\xf1\xf2\xf0\xee\xea\xe0' >>> bytes("строка123", "ascii", "ignore") b'123' bytes(<Последовательность>) — преобразует последовательность целых чисел от 0 до 255 в объект типа bytes . Если число не попадает в диапазон, возбуждается исключение ValueError : >>> b = bytes([225, 226, 224, 174, 170, 160]) >>> b b'\xe1\xe2\xe0\xae\xaa\xa0' >>> str(b, "cp866") 'строка' bytearray(<Строка>, <Кодировка>[, <Обработка ошибок>]) — преобразует строку в объ- ект типа bytearray . В третьем параметре могут быть указаны значения "strict" (значе- ние по умолчанию), "replace" или "ignore" : >>> bytearray("строка", "cp1251") bytearray(b'\xf1\xf2\xf0\xee\xea\xe0') bytearray(<Последовательность>) — преобразует последовательность целых чисел от 0 до 255 в объект типа bytearray . Если число не попадает в диапазон, возбуждается ис- ключение ValueError : >>> b = bytearray([225, 226, 224, 174, 170, 160]) >>> b 50 Часть I. Основы языка Python bytearray(b'\xe1\xe2\xe0\xae\xaa\xa0') >>> str(b, "cp866") 'строка' list(<Последовательность>) — преобразует элементы последовательности в список: >>> list("12345") # Преобразование строки ['1', '2', '3', '4', '5'] >>> list((1, 2, 3, 4, 5)) # Преобразование кортежа [1, 2, 3, 4, 5] tuple(<Последовательность>) — преобразует элементы последовательности в кортеж: >>> tuple("123456") # Преобразование строки ('1', '2', '3', '4', '5', '6') >>> tuple([1, 2, 3, 4, 5]) # Преобразование списка (1, 2, 3, 4, 5) В качестве примера рассмотрим возможность сложения двух чисел, введенных пользовате- лем. Как вы уже знаете, вводить данные позволяет функция input() . Воспользуемся этой функцией для получения чисел от пользователя (листинг 2.1). Листинг 2.1. Получение данных от пользователя # -*- coding: utf-8 -*- x = input("x = ") # Вводим 5 y = input("y = ") # Вводим 12 print(x + y) input() Результатом выполнения этого скрипта будет не число, а строка 512 . Таким образом, следу- ет запомнить, что функция input() возвращает результат в виде строки. Чтобы просуммиро- вать два числа, необходимо преобразовать строку в число (листинг 2.2). Листинг 2.2. Преобразование строки в число # -*- coding: utf-8 -*- x = int(input("x = ")) # Вводим 5 y = int(input("y = ")) # Вводим 12 print(x + y) input() |