Доброго времени суток, читатели, зрители моего канала programmer's notes.
Приложение к уроку
Встроенные классы Python
Отойду несколько от порядка, который был задан видео-уроком. Начну с функций, которые не так часто используются в непосредственно в программировании (за исключением, пожалуй type()), но они бывают очень полезны для исследовательской работы программисты.
- type() - получить тип переменной;
- id() - получить идентификатор объекта.
- dir() - получить список методов и свойств объекта;
Функция type()
Простой фрагмент
a = 10
b = 10.234
print(type(a))
print(type(b))
Результат выполнения фрагмента
<class 'int'>
<class 'float'>
Что это означает с точки зрения объектно-ориентированного программирования?
Что переменные a и b являются членами классов или объектами классов. a - объект класса int, класса целых чисел, b - объект класса float, класса чисел с плавающей точкой. Т.е. мы с самого начала нашего вводного курса работали с объектами. И когда мы пишем a = 33 это означает: создается объект - целое число равное 33, создается переменная a, которая указывает на объект.
Ещё один фрагмент
ls = [2, 1, 4]
st = {'qwerty', 2, 1}
print(type(ls))
print(type(st))
Результат выполнения
<class 'list'>
<class 'set'>
Т.е. нами было создано два объекта: класса список и класса множество.
А как программно проверять тип переменной с помощью функции type()? Да все просто
Соответственно можно использовать ключевые слова list, int, float, dict и т.д.
С помощью свойства __name__ можно получить строку-название класса и, соответственно писать
if type(ls).__name__ == 'list':
ну и подобным же образом для других типов.
Но есть и другая функция, весьма, кстати, удобная
isinstance() - возвращает True или False.
Вот фрагмент
Функция id()
Чем интересная данная функция? Она возвращает внутренний идентификатор объекта, на который указывает данная переменная.
Рассмотрим фрагмент
a = 10
b = a
# a и b указывают на один оюъект
print(id(a))
print(id(b))
a = a + 1 # новый объект
# a и b указывают на разные объекты
# b указывает на старый
print(id(a))
print(id(b))
b = 100
# теперь и b указывает на другой объект
# а объект равный 10 остался в памяти без указателя
# и будет автоматически удалён
print(id(a))
print(id(b))
Результат выполнения фрагмента
140380570077776
140380570077776
140380570077808
140380570077776
140380570077808
140380570269136
Соотнесите результат выполнения и текст фрагмента, и всё станет понятным
Числа в python называются статическими типами. Их изменения приводят к созданию нового типа. К статическим типам относятся также строки. Например. запись
s = s.upper()
Создает новый объект, в котором все буквы становятся заглавными по отношению к старому объекту, который будет удалён из памяти.
Другой тип данных динамический. С ним уже не всё так просто.
Следующий фрагмент
ls = [1, 2, 4, 2]
ll = ls
# переменные указывают на один и тот же объект
print(id(ls))
print(id(ll))
ls[3] = 5
# содержимое изменилось, а объект тот же
print(id(ls))
print(id(ll))
ls = ls + [30, 300, 3000]
# а вот теперь ls будет указывать на другой объект
print(id(ls))
print(id(ll))
Результат выполнения фрагмента
140235803221952
140235803221952
140235803221952
140235803221952
140235803167104
140235803221952
Т.е. в одном случае, если мы меняем элемент списка, объект остается тот же, а вот если мы складываем два списка, то создает новый объект, а на старый по-прежнему указывает переменная ll. Тут важно, что два списка складываются. Добавление же элементов, скажем с помощью append() также объект не меняет.
Функция dir()
Это совсем такая забавная функция. В программе ее нет смысла использовать. Это справка по тому, какие методы и свойства есть у объекта или класса. Я то вообще этим никогда не пользуюсь, смотрю документацию - это самый правильный путь, как я думаю. Но для исследования и более глубокого понимания Python, она хороша.
Но вот фрагмент
a = 23
print(dir(a))
print(dir(list))
Результат выполнения
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__',
'__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__',
'__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__im
ul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
Результат, как видим, выдаётся как список имен методов и свойств. Из примера ясно, что в качестве аргумента может быть и объект и класс. Конечно, некоторые элементы списков нам с вами знакомы. Это касается списка, конечно. С числовыми типами мы не использовали методов. Но при желании, конечно можно
a = 123
b = a.__add__(10)
print(b)
print(a)
Результат выполнения
133
123
Обратим внимание, что метод создает новый объект, в полном соответствии с тем, что числовые типы являются статическими. Обратим также внимание на свойство __doc__, которое по смыслу должно содержать объяснение по данному объекту.
Например
a = 123
print(a.__doc__)
print(a.__add__.__doc__)
Результат выполнения я приводить не буду, чтобы не загромождать изложение. Вы можете сделать это сами. В первом случае дает объяснение фактически класса int. Во втором - описание метода. Но в python всё является объектами, поэтому метод это тоже объект. И у него есть свои методы и свойства (sic!).
Функции тоже, являются объектами класса function. Это проверяется опять с помощью функции type().
Результат выполнения данного фрагмента
<class 'function'>
None
С классом понятно, но понятно и со свойством __doc__. Мы сами написали функцию и не указали для нее документации. А вот как это можно сделать
Результат выполнения
Это простая функция для
демонстрации того, как писать
документацию для функции
Ну пока, всё!
Всего наилучшего. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.