Я въезжаю в Python
часть 2

Я въезжаю в Python,
часть 2

Содержание:

Введение: Синтаксис

Python – язык динамической типизации. Мы не объявляем переменные как в других языках, а присваиваем указатели объектам. Указатели – не имеют типа, тип имеют объекты, на которые они ссылаются.

Синтаксис языка Python, очень красив и практически исключает написание гавно-кодов ( при особом желании, это конечно возможно ). В Пайтоне блоки кода оформляются табуляцией, а не скобками как во многих других языках, что очень повышает читабильность кода, как разработчиком, так и другими программистами. В Пайтоне, порог вхождения и понимания программы - намного выше чем в других языках.

Комментарии кода в Python обрамляются решеткой #

Начнем изучение Python с основных типов данных, ибо любая хорошо написанная программа должна оперировать правильно сформированными и подобранными структурами данных.

Не изменяемые типы данных:

int()

Целое число: 1, 2, 3, 4 и т.д.

float()

Число с плавающей точностью, например 0.3, 1.5, 23.45 и т.д. ввести можно опуская нули: .3, 3. и т.д.

complex()

Комплексное число, например 1+5j, 2+2j и т.д.

str()

Строковые данные, вводятся обрамлясь ковычками: 'stroka' или "stroka"

tuple()

Кортеж данных, записывается в круглых скобках ( )

Например:

( 1, 2, 3 )

Кортеж можно индексировать, но удалять что либо из него или изменять – нельзя.

( 1, 2, 3 )[0] #обращаемся к первому элементу кортежа, выведет 1

Кортеж может содержать любые объекты, например:

( 1, 'stroka', ( 1, 2, 3, 'stroka' ) )

Изменяемые типы данных:

list()

Список данных, записывается в квадратных скобках [ ]

Может содержать любые данные. Индексируемый и изменяемый.

[ 1, 2, 4 ][0] #обращаемся к первому элементу списка, выведет 1
[ 1, ( 'b', 2 ), [ 1, 2, 3 ] ] # может содержать любые данные

dict()

Словарь данных, записывается в фигурных скобках { }

Может содержать любые данные. Не индексируемый, изменяемый.

В отличии от списка и кортежа, в словаре нет порядка и доступ к данным можно получить только по ключу. Проводя аналогию с другими языками программирования, можно поставить на одну полочку с ассоциативным массивом.

{ '1' : 'a', 'key' : 'test' }['key'] #обращаемся элементу словаря по ключу, выведет 'test'

file()

Файл - в python является типом данных, не удивляйтесь

file( 'D:\Projects\main.tpl' ) #открывает файл

Файл так же является объектом и имеет свой набор атрибутов.

Операции над объектами:

Рассмотрим несколько простейших операции с данными, откроем IDLE:

2**10 # возведем 2 в 10 степень

Интерпретатор сразу выдает нам результат 1024, так как Python – является динамическим языком программирования. То же произойдет и с другими стандартными математическими операциями. Но интереснее немного другое: а именно типы объектов и операции над ними.

1/3 #операция деления

Интерпретатор вернет 0

Программа работает правильно. Поскольку не указан точный тип данных, над которыми производится операция, пайтон вычисляет результат с заданным типом по умолчанию: 1 и 3 в данном случае - имеют тип int.

Что бы получить желаемый результат, необходимо указать интерпретатору что, хотя бы одно, из заданных чисел, имеет тип float ( число с плавающей точностью ):

1/3.0

Вернулось 0.333333333

При делении целого числа, на число с плавающей точностью результат взял тип float. И вот почему: если операции над разными объектами разрешены, то результат всегда приводится к более сложному типу.

Можно воспроизвести тоже действие таким образом:

float( 1 )/3

Интерпретатор вернет нам ожидаемое: 0.333333333

Операция присваивания:

Что происходит при вводе данных:

2**10

Пайтон создает ячейку в памяти с записью 2, ячейку с записью 10, производит действие, результат 1024 записывается в новую ячейку, выводится на экран и ячейки уничтожаются. Пайтон – язык с автоматической сборкой мусора, тоесть с высвобождением всей не используемой памяти. Несмотря на то, что результат мы видим на экране, в памяти этих объектов уже не существует.

Но, если мы, установим на объект указатель, то объект будет хранится в памяти пока на него ссылается хотя бы один указатель. Именование объектов реализуется при помощи операции присваивания, например:

b = 10

На самом деле происходит следующее: литерал 10 создает объект в памяти, а b ссылается на этот объект. То есть, 10 – это "реально" существующий объект с набором атрибутов, а b – всего лишь указатель. 10 имеет тип int(), а b, ссылается на ячейку в памяти и типа не имеет.

Продолжим:

b = '10'

При этом создается объект str( '10' ), а предыдущий объект на который ссылался указатель b, int( 10 ) – высвобождается из памяти.

Узнать тип объекта можно встроенной функцией type()

type( b )

Интерпретатор вернет нам: <type 'str'>

Копирование объектов:

В начале статьи, я разбил типы данных на изменяемые и не изменяемые, сейчас объясню почему:

a = [ 1, 2, 3 ] #создадим список

x = a
x[1] = 'test'
print a

Ответ: [ 1, 'test', 3 ]

Вот это прикол! Копирования объектов не происходит, так как указатели - это только ссылки на объекты. Происходит следующее: a - создает указатель, а при присвоении x = a, x - не дублирует объект, а создает точно такой же указатель на объект.

Проверить это можно встроенной функцией is:

x is b #выведет True

Это значит что указатели ссылаются на один и тот же объект в памяти.

Примерно то же самое происходит и со строковыми данными str():

b = 'text'
x = b
x is b #выведет True
x = 'bla'
print b, x #выведет на экран: ( 'text', 'bla' )

При присвоении x = b, указатель ссылается на ту же ячейку в памяти что и b, НО при присвоении x = 'bla', x - указывает на новый объект в памяти и не изменяет объект b ( точнее ячейку в памяти на которую указывает b )

b = 'text'
b[2] #выведет x
b[2] = 'ept' #выдаст ошибку Traceback

Именно поэтому str() - не изменяемый объект в памяти, мы можем индексировать его, но изменять "отдельный элемент" - нет. Так как же, блять, копировать объект в новую ячейку памяти? Очень просто:

b = [ 1, 2, 3 ]
x = b[:] #сделаем срез с первого по последний элемент
x is b #вернет False

Дублировать объект можно с помощью среза [:], при необходимости можно указать с какого элемента по какой копировать: [1:3] и т.д.

Атрибуты объектов:

У каждого объекта в объектно-ориентированном языке программирования есть атрибуты, которые являются его свойствами и методами. У любого объекта можно посмотреть его атрибуты встроенной функцией dir(). Протестируем:

b = 'str'
dir ( b )

Интерпритатор вернет нам список атрибутов:

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

К примеру атрибут index, указывает на то что объект можно индексировать: b[0], b[1] и т.д. Для того чтобы узнать, что делает любой из атрибутов, достаточно воспользоваться функцией help(), например:

help( b.upper )

Ответ:

Help on built-in function upper:

upper(...)
    S.upper() -> string
    
    Return a copy of the string S converted to uppercase.

Узнаем, что upper это встроенный метод, значит его можно вызвать, при переводе становится понятно, что upper конвертирует символы строки в верхний регистр.

b.upper()

ответ:

'STR'

Все атрибуты которые обрамляются двумя подчеркиваниями слева и справа – это служебные методы, которые пользователем напрямую вызываться не должны, но могут.

Стоит обратить внимание, что даже у объектов, которые мы не сохраняем в памяти есть возможность напрямую обратиться к атрибутам:

dir( 'stroka' ) #смотрим список атрибутов
'stroka'.upper()

Но у целого числа нельзя напрямую вызвать атрибуты, т.к. написание к примеру:

dir( 1 )
1.__str__()

Выдаст ошибку синтаксиса: SyntaxError: invalid syntax

Так как написание литерала совпадает с литеральным представлением чисел с плавающей точностью. Если слева от точки стоит число, пайтон распознает тип этого объекта как число с плавающей точностью ( float ).

Провести операцию над такими числами можно так:

int( 1 ).__str__()

И именно поэтому имена объектов не могут начинаться с цифр. А только с букв, ну или с нижнего подчеркивания.

Итоги:

Не изменяемые типы данных: int(), float(), complex(), str(), tuple().

Изменяемые типы данных: list(), dict(), file().

Python – язык динамической типизации. Мы не объявляем переменные как в других языках, а присваиваем указатели объектам. Указатели – не имеют типа, тип имеют объекты, на которые они ссылаются.

Копировать объекты - можно срезом [:].

dir() - встроенная функция для просмотра атрибутов объекта.

help() - встроенная функция-справочник для просмотра документации атрибутов объекта.


08 марта 2012, 12:31
Python


Авторизация
Зайди на сайт с помощью соц. сети: