Данные, которыми мы оперируем в своих программах, могут обладать важными атрибутами. В Python атрибуты встроены прямо в язык. Кроме статических свойств у данных существуют методы - функции, находящиеся внутри свойств. Свойства и методы - такие же выражения, как переменные или вызовы функции, а значит, их можно всячески комбинировать. Глубже эти темы разбираются на отдельных курсах, посвященных объектно-ориентированным возможностям Python. Мы же в этом модуле изучим основы.
В программировании мы постоянно оперируем данными, создаем числа, строки, выполняем над ними различные операции и затем используем полученный результат. Для операций у нас есть либо операторы, либо функции:
# Сложение с помощью оператора +
1 + 3 # 4
# Подсчет длины с помощью функции len()
name = 'Hexlet'
len(name) # 6
В такой схеме у нас есть четкое разделение: данные отдельно, функции отдельно. Но это не единственный способ организации кода. В Python наравне с таким разделением, используется и другой подход - объектно-ориентированный (ОО).
Объектно-ориентированный код строится на объединении данных и функций в одну сущность, называемую объектом. Данные в таком случае называются атрибутами, а функции - методами.
Как это выглядит:
name = 'Hexlet'
# Метод upper()
upper_name = name.upper()
print(upper_name) # => 'HEXLET'
Строки в Python - объекты. Выше мы видим вызов метода, то есть функции, которая связана со строкой. Вызов происходит через точку, идущую сразу за именем переменной. В остальном методы работают как обычные функции. Вызов можно делать и напрямую:
'Hexlet'.upper() # 'HEXLET'
В строки встроено множество разнообразных методов, которые нужны в повседневной жизни разработчика. Посмотреть их список можно в документации. Вот несколько полезных примеров:
name = 'Python'
# Возвращает индекс первого вхождения буквы в строку
name.find('t') # 2
# Переводит в нижний регистр
name.lower() # 'python'
# Заменяет одну подстроку другой
name.replace('on', 'off') # 'Pythoff'
То же самое касается чисел и остальных типов данных, которые мы пока не изучали. Проще говоря, в Python почти все является объектом:
x = -5
# Возвращает модуль числа
# Имя выглядит странно, но это действительно имя метода
x.__abs__()
Почему такое странное имя метода с двумя подчеркиваниями в начале и в конце? В Python так называют методы, которые не предназначены для прямого вызова. Для них созданы функции, которые внутри себя уже сами делают вызовы методов:
x = -5
abs(x) # вызывает x.__abs__()
# -5 в 3 степени
pow(x, 3) # вызывает x.__pow__(3)
Зачем это нужно? Создатель Python решил, что будет нагляднее, если математические или похожие на математические операции будут выражены функциями, как это привычнее для тех, кто изучал математику. Он хотел, чтобы такие функции воспринимались как операции, типа сложения или вычитания. Кстати, точно так же работает функция len()
:
len('Hexlet') # Вызывает 'Hexlet'.__len__()
Кроме методов у объектов есть атрибуты, правда, у встроенных в Python объектов их крайне мало. Один из немногих примеров - это атрибут __doc__
у функций, который возвращает документацию функции. Да, функции - тоже объекты:
len.__doc__ # 'Return the number of items in a container.'
Атрибуты работают и выглядят как переменные, только указываются через точку после объекта.
Что напечатает на экран последний вызов?
name = 'Tirion'
print(name.upper()) # => TIRION
print(name) # => ?
Ответ на этот вопрос зависит от того, как вы поняли урок про неизменяемость примитивных типов данных. Вызов метода .upper()
возвращает новое значение, в котором все буквы преобразованы в верхний регистр, но он не меняет исходную строку. Поэтому внутри переменной окажется старое значение: 'Tirion'
. Эта логика справедлива для методов всех примитивных типов.
Вместо изменения значения можно заменить значение. Для этого понадобятся переменные:
name = 'Tirion'
name = name.upper()
print(name) # => TIRION
Методы — такие же выражения, как переменные или вызовы функции, а значит, их можно всячески комбинировать.
Использование в операциях:
name = 'Shaya'
'hi, ' + name.upper() + '!' # hi, SHAYA!
Использование в аргументах функций:
name = 'robb'
print(name.lower()) # => robb
num1 = 5
num2 = 30
# bit_length() - вычисляет количество бит, необходимых для представления числа в двоичном виде
print(num1.bit_length() + num2.bit_length()) # => 8
Вам ответят команда поддержки Хекслета или другие студенты.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт