class FootballClub:
num_clubs = 0
@classmethod
def count_clubs(cls):
msg = f"Клубов в нашей лиге: {cls.num_clubs}."
print(msg)
def __init__(self, name, description=""):
self.name = name
self.description = description
FootballClub.num_clubs += 1
def describe_club(self):
msg = f"{self.name}: {self.description}"
print(msg)
clubs = []
club = FootballClub("Манчестер Юнайтед")
club.description = "Манчестер, Англия"
clubs.append(club)
club = FootballClub("Реал")
club.description = "Мадрид, Испания"
clubs.append(club)
club = FootballClub("Ювентус")
club.description = "Турин, Италия"
clubs.append(club)
for club in clubs:
club.describe_club()
FootballClub.count_clubs()
Сначала вне метода
__init__ создадим атрибут класса num_clubs. Обратим внимание, что никакой приставки в виде self перед этим атрибутом у нас нет, потому что он связан не с экземпляром класса, а с классом в целом.Далее пишем классовый метод, предварив его декоратором
@classmethod. При помощи этого декоратора в метод передается весь класс. По умолчанию в классовых методах сам класс обозначается параметром cls. Внутри самого метода доступ к атрибуту класса можно получить через точечную нотацию. Так, к числу клубов в нашей лиги мы получаем доступ следующим образом: cls.num_clubs.Чтобы количество клубов всегда было актуальным, при создании каждого нового экземпляра класса нам нужно увеличивать число, записанное в
num_clubs, на единицу. Мы сделали это в методе __init__:
def __init__(self, name, description=""):
self.name = name
self.description = description
FootballClub.num_clubs += 1
Так как метод
__init__ не принимает cls в качестве аргумента, доступ к атрибуту num_clubs мы получаем через название класса. В конце мы вызываем метод класса, снова обратившись к нему по названию:
FootballClub.count_clubs()
Вывод будем следующим:
Манчестер Юнайтед: Манчестер, Англия
Реал: Мадрид, Испания
Ювентус: Турин, Италия
Клубов в нашей лиге: 3.
Обращаться к атрибутам класса и классовым методам можно несколькими способами, не только так, как мы показали выше.
Доступ к атрибуту класса по названию класса
Несмотря на то, что класс передается в классовый метод автоматически, получить доступ к атрибутам класса можно и через его название:
@classmethod
def count_clubs(cls):
msg = f"Клубов в нашей лиге: {FootballClub.num_clubs}."
print(msg)
Делать так не имеет никакого смысла, ведь можно использовать
cls, но ошибки при таком подходе не случится.Вызов классового метода из экземпляра класса
Вызвать классовый метод можно и из экземпляра класса. Следующий код вполне рабочий:
club = FootballClub("Манчестер Юнайтед")
club.description = "Манчестер, Англия"
club.count_clubs()
Результат будет таким же, как и в случае с
FootballClub.count_clubs().Вызов классового метода через экземпляр класса может пригодиться, если вы работаете с объектом класса в модуле, который не имеет прямого доступа к самому классу. В таком случае можно не импортировать класс в модуль целиком, а обойтись вызовом метода напрямую из объекта, который у вас уже есть.
Подобная гибкость облегчает работу, поскольку разработчику необязательно думать о том, что происходит под капотом в том или ином классе. Можно просто пользоваться результатами труда тех, кто разработал и поддерживает саму библиотеку.
Доступ к атрибуту класса из обычного метода класса
🔥5
Атрибутами класса можно пользоваться и в обычных методах класса. Например, если нам нужно расширить описание футбольного клуба, включив в него информацию о количестве команд в его лиге:
Это самый обычный метод, связанный с конкретным экземпляром класса, поэтому в него передается объект
Можно ли получить доступ к атрибутам класса через
Ответ: да, можно. Если во всём классе у нас есть только один атрибут с данным именем, то ошибки не будет:
Этот код будет работать так же, как и код из примера выше.
На что обращать внимание?
Сложности начинаются при попытке записать новое значение в атрибут класса с помощью объекта
Мы, как и раньше, увеличиваем число клубов на единицу, когда инициализируем новый объект класса. Но так как теперь мы делаем это через объект
В атрибуте
В следующий раз поговорим о методах
Пост на сайте
Поддержать проект
#Python #ООП #код_в_мешке #объект #атрибут #класс #init #self #метод
def describe_club(self):
msg = (f"{self.name}: {self.description}\n"
f"Клубов в лиге: {FootballClub.num_clubs}")
print(msg)
Это самый обычный метод, связанный с конкретным экземпляром класса, поэтому в него передается объект
self. Но и в нём можно получить доступ к атрибутам всего класса, используя название класса.Можно ли получить доступ к атрибутам класса через
self?Ответ: да, можно. Если во всём классе у нас есть только один атрибут с данным именем, то ошибки не будет:
def describe_club(self):
msg = (f"{self.name}: {self.description}\n"
f"Клубов в лиге: {self.num_clubs}")
print(msg)
Этот код будет работать так же, как и код из примера выше.
На что обращать внимание?
Сложности начинаются при попытке записать новое значение в атрибут класса с помощью объекта
self. Дело в том, что, используя self, вы создаете новый атрибут именно экземпляра, если такой атрибут не был создан ранее. В такой редакции код не будет давать нам искомый результат:
class FootballClub:
num_clubs = 0
@classmethod
def count_clubs(cls):
msg = f"Клубов в нашей лиге: {cls.num_clubs}."
print(msg)
def __init__(self, name, description=""):
self.name = name
self.description = description
self.num_clubs += 1
def describe_club(self):
msg = (f"{self.name}: {self.description}\n"
f"Клубов в лиге: {self.num_clubs}")
print(msg)
Мы, как и раньше, увеличиваем число клубов на единицу, когда инициализируем новый объект класса. Но так как теперь мы делаем это через объект
self, а не через название класса, мы не меняем атрибут класса num_clubs, а создаём новый атрибут экземпляра с таким же точно названием. И теперь у нас два атрибута с одинаковым названием num_clubs: один относится к классу, а другой - к конкретному его экземпляру. И вывод у кода будет следующий:
Манчестер Юнайтед: Манчестер, Англия
Клубов в лиге: 1
Реал: Мадрид, Испания
Клубов в лиге: 1
Ювентус: Турин, Италия
Клубов в лиге: 1
Клубов в нашей лиге: 0.
В атрибуте
num_clubs каждого экземпляра класса теперь записано по единице, но атрибут num_clubs класса так и не изменился: это по-прежнему ноль. Если логика в этом случае не очень понятно, можно просто запомнить важный вывод. Работая с атрибутом класса внутри самого класса, всегда используйте cls, если речь о классовом методе, и название класса, если речь об обычном методе. И постарайтесь не создавать атрибутов класса и атрибутов экземпляра с одинаковым названием. В следующий раз поговорим о методах
__str__ и __repr__.Пост на сайте
Поддержать проект
#Python #ООП #код_в_мешке #объект #атрибут #класс #init #self #метод
🔥9
Forwarded from Заметки на салфетке
В воскресенье в 18:00 состоится третий стрим.
Продолжаем делать Telegram-бота для управления VPSкой.
Что мы уже сделали:
- Выполнение произвольной команды с выводом результата.
- Выполнение последовательности команд с запоминанием изменения пути при использовании команды
- Оповещение администратора о запуске-остановке бота и меню.
- Меню управления Docker-контейнерами.
Что ещё в планах:
- Сделать вывод используемых сервером ресурсов (ОЗУ, ЦПУ).
- Сделать меню с избранными командами. Для реализации необходимо подключить БД используя SQLAlchemy.
- Сделать обработку сообщений только от администратора.
Если у вас есть ещё идеи - пишите в комментариях!
Всех жду Воскресенье 18:00: https://www.youtube.com/@codeonanapkin
P.S. Всем, кто поддерживает канал на Boosty доступен репозиторий с исходным кодом проекта.
Продолжаем делать Telegram-бота для управления VPSкой.
Что мы уже сделали:
- Выполнение произвольной команды с выводом результата.
- Выполнение последовательности команд с запоминанием изменения пути при использовании команды
cd.- Оповещение администратора о запуске-остановке бота и меню.
- Меню управления Docker-контейнерами.
Что ещё в планах:
- Сделать вывод используемых сервером ресурсов (ОЗУ, ЦПУ).
- Сделать меню с избранными командами. Для реализации необходимо подключить БД используя SQLAlchemy.
- Сделать обработку сообщений только от администратора.
Если у вас есть ещё идеи - пишите в комментариях!
Всех жду Воскресенье 18:00: https://www.youtube.com/@codeonanapkin
P.S. Всем, кто поддерживает канал на Boosty доступен репозиторий с исходным кодом проекта.
👍3🔥1
Доброго пятничного вечера, Друзья!
Пришло время для отдыха и развлечений. Закройте дверь за повседневными заботами и погрузитесь в мир киноискусства, который заставит вас забыть о всех проблемах. Приготовьте вкусные угощения, уютно устроившись на диване, и позвольте себе погрузиться в захватывающий мир кино. Пусть каждый кадр наполнит вас эмоциями и заставит забыть о повседневной суете. Наслаждайтесь просмотром фильма и наслаждайтесь вечером пятницы в полной мере!
Фильм: Оппенгеймер
Год: 2023
История физика-теоретика Джулиуса Роберта Оппенгеймера, считающегося «отцом атомной бомбы». В 1940-х годах в рамках «Манхэттенского проекта» он руководил разработкой первого ядерного оружия в Лос-Аламосской национальной лаборатории. «Оппенгеймер» (2023) — биографическая драма Кристофера Нолана с Киллианом Мерфи в главной роли, основанная на книге «Американский Прометей: Триумф и трагедия Дж. Роберта Оппенгеймера» Кая Берда и Мартина Дж. Шервина.
https://www.sspoisk.ru/film/4664634/
Приятного просмотра
Пришло время для отдыха и развлечений. Закройте дверь за повседневными заботами и погрузитесь в мир киноискусства, который заставит вас забыть о всех проблемах. Приготовьте вкусные угощения, уютно устроившись на диване, и позвольте себе погрузиться в захватывающий мир кино. Пусть каждый кадр наполнит вас эмоциями и заставит забыть о повседневной суете. Наслаждайтесь просмотром фильма и наслаждайтесь вечером пятницы в полной мере!
Фильм: Оппенгеймер
Год: 2023
История физика-теоретика Джулиуса Роберта Оппенгеймера, считающегося «отцом атомной бомбы». В 1940-х годах в рамках «Манхэттенского проекта» он руководил разработкой первого ядерного оружия в Лос-Аламосской национальной лаборатории. «Оппенгеймер» (2023) — биографическая драма Кристофера Нолана с Киллианом Мерфи в главной роли, основанная на книге «Американский Прометей: Триумф и трагедия Дж. Роберта Оппенгеймера» Кая Берда и Мартина Дж. Шервина.
https://www.sspoisk.ru/film/4664634/
Приятного просмотра
🔥5👍1
🔥3
Код на салфетке
ООП на Python. ч. 2. Статические методы Автор: Андрей Лебедев Продолжаем цикл постов об ООП на Python. В прошлый раз мы говорили об ООП как таковом, об объекте self и о методе __init__. На сей раз мы поведем речь о методах классов. И начнём мы со статических…
Вчера мы опубликовали задачу №14, которая является закреплением темы, начатой в посте "ООП на Python. ч. 2. Статические методы". С задачей справилось всего 7 человек из 26...
Код задачи:
Разбор задачи.
Привычного разбора задачи не будет, поскольку задача повторяет описанное в посте. Если вы не читали пост "ООП на Python. ч. 2. Статические методы", то настоятельно рекомендую это сделать, как минимум чтобы закрыть пробел в понимании работы методов класса.
Код задачи:
class PopSinger:
num_singers = 0
@classmethod
def count_singers(cls):
msg = f"Певцов на нашем концерте: {cls.num_singers}."
print(msg)
def __init__(self, name, description=""):
self.name = name
self.description = description
self.num_singers += 1
klava = PopSinger("Клава Кока", "27 лет, женщина")
insta = PopSinger("Инстасамка", "23 года, женщина")
feduk = PopSinger("Федук", "32 года, мужчина")
PopSinger.count_singers()
Разбор задачи.
Привычного разбора задачи не будет, поскольку задача повторяет описанное в посте. Если вы не читали пост "ООП на Python. ч. 2. Статические методы", то настоятельно рекомендую это сделать, как минимум чтобы закрыть пробел в понимании работы методов класса.
🔥4
Forwarded from Заметки на салфетке
🤯Два с половиной часа! Можно считать, что бот готов. По мелочи пройтись напильником, привести к одному виду, но он работает как задумывалось изначально.
Запись: https://www.youtube.com/watch?v=ZmSrlHJQikw
Исходный код доступен для подписчиков на Boosty.
Дальше если и буду дорабатывать бота, то самостоятельно, обновляя его в репозитории.
Идей на следующее воскресенье у меня нет. Что посоветуете? Что было бы вам интересно увидеть?
Запись: https://www.youtube.com/watch?v=ZmSrlHJQikw
Исходный код доступен для подписчиков на Boosty.
Дальше если и буду дорабатывать бота, то самостоятельно, обновляя его в репозитории.
Идей на следующее воскресенье у меня нет. Что посоветуете? Что было бы вам интересно увидеть?
🔥8❤3
Сравнение интерпретатора Python и компилятора C
Автор: Arduinum628
Всем доброго дня! Сегодня я продолжу свою рубрику о сравнении работы двух языков программирования Python и C. В предыдущей статье я сравнивал типизацию Python и C и показал процесс компилирования программы на C. Компиляция проводилась чтобы посмотреть на результат работы программы C. Тут сразу у читателя могли появиться вопросы: "В Python нет компиляции, что же происходит там?" или "Где сравнение того, что происходит под капотом у этих двух языков?". Конечно, я не могу обойти эту интересную и сложную тему без освещения в своей рубрике. Сегодня я сравню интерпретатор Python и компилятор C. Поэтому возьмите себе вкусняшек пожевать и чаю - мы погружаемся ещё глубже в сравнение Python и C.
Сравнение компилятора и интерпретатора
Автор: Arduinum628
Всем доброго дня! Сегодня я продолжу свою рубрику о сравнении работы двух языков программирования Python и C. В предыдущей статье я сравнивал типизацию Python и C и показал процесс компилирования программы на C. Компиляция проводилась чтобы посмотреть на результат работы программы C. Тут сразу у читателя могли появиться вопросы: "В Python нет компиляции, что же происходит там?" или "Где сравнение того, что происходит под капотом у этих двух языков?". Конечно, я не могу обойти эту интересную и сложную тему без освещения в своей рубрике. Сегодня я сравню интерпретатор Python и компилятор C. Поэтому возьмите себе вкусняшек пожевать и чаю - мы погружаемся ещё глубже в сравнение Python и C.
Сравнение компилятора и интерпретатора
🔥5
Для того чтобы увидеть полную картину, в этой статье я сравню все фазы от написания кода в IDE до выполнения работы программы. Так вы увидите весь процесс более глубоко и вам будет проще понять какие процессы прячутся во время выполнения программ на C и Python. Я люблю показывать работу программы на конкретных примерах, а не абстрактно, и в этом нам помогут циклы
Фаза 1: написание программы в IDE
Данная фаза довольно банальна, но без неё не обходится написание ни одной программы. Начнём с идеи того, что мы реализуем в коде. Думаю, для примера нам не нужно писать что-то сложное. Давайте напишем цикл, который будет проходить по списку чисел, запишет в переменную сумму этих чисел и выдаст на экран результат суммы чисел из списка. Начнём с реализации данной программы на языке Python.
Пример выше на Python довольно простой. У нас есть список чисел
Я буду пропускать то, что вы уже знаете из предыдущих глав, и сосредоточусь на новом для вас синтаксисе. Давайте посмотрим на пример выше внимательнее. Начнём со строки
for. Заодно я наглядно покажу в чём схожесть и различия по синтаксису при написании этого цикла на Python и C.Фаза 1: написание программы в IDE
Данная фаза довольно банальна, но без неё не обходится написание ни одной программы. Начнём с идеи того, что мы реализуем в коде. Думаю, для примера нам не нужно писать что-то сложное. Давайте напишем цикл, который будет проходить по списку чисел, запишет в переменную сумму этих чисел и выдаст на экран результат суммы чисел из списка. Начнём с реализации данной программы на языке Python.
nums_list = [1, 3, 4, 50, 20]
sum_nums = 0
for num in nums_list:
sum_nums += num
print(f'Сумма чисел списка = {sum_nums}')
Пример выше на Python довольно простой. У нас есть список чисел
nums_list, который мы обходим циклом for. В цикле for мы проходим по списку чисел и складываем каждое число из списка с числом из переменной sum_nums, где хранится результат суммы чисел из списка. В конце функция print выдаст нам результат в виде отформатированной строки при помощи f строки, в которую мы вставляем результат суммы чисел из переменной sum_nums. Давайте теперь напишем реализацию подобного кода на языке C.#include <stdio.h>
int main(){
int arr_nums[] = {1, 3, 4, 50, 20};
int size = sizeof(arr_nums) / sizeof(arr_nums[0]);
int sum_nums = 0;
for (int i=0; i < size; i++) {
sum_nums += arr_nums[i];
}
printf("Сумма чисел массива = %d\n", sum_nums);
return 0;
}
Я буду пропускать то, что вы уже знаете из предыдущих глав, и сосредоточусь на новом для вас синтаксисе. Давайте посмотрим на пример выше внимательнее. Начнём со строки
int arr_nums[] = {1, 3, 4, 50, 20}; слева направо. Начало int arr_nums[] - это массив целых чисел, а далее ему присваивается его содержимое = {1, 3, 4, 50, 20};, то есть числа для массива. Читатель может задаться вопросом, а что такое массив и чем он отличается от списка? Могу сказать, что тема коллекций достаточно обширна и предлагаю её раскрыть в следующей моей статье. Пока ограничусь тем что массив, или array, в языке С имеет фиксированную длину в отличие от списка, или list, в Python, который является динамическим. Это означает что в array C нельзя добавить новый элемент после его создания (если превышен размер массива), в то время как в list Python нет фиксированного размера и можно добавить сколько угодно новых элементов в список. Компилятор в C будет автоматически определять размер массива на основе количества его элементов. Также размер массива можно указать явно int arr_nums[5] = {1, 3, 4, 50, 20};, где цифра в квадратных скобках это количество элементов массива. В следующей главе я покажу вам, что будет если указать число меньше или больше количества чисел в массиве :) Перейдём к следующей строке кода int size = sizeof(arr_nums) / sizeof(arr_nums[0]);. Первая часть строки нам уже проста для понимания - это целочисленная переменная int size, которая, как мы видим из названия, переводится на русский как размер. Идём по строке кода далее и видим, что ей присваивается результат следующего математического выражения = sizeof(arr_nums) / sizeof(arr_nums[0]);.🔥3👍1
Давайте рассмотрим левый операнд
Фаза 2: препроцессинг
После того как мы написали программный код, мы обязательно захотим его выполнить и посмотреть как работает наша программа. Для этого мы запускаем процесс компиляции в C.
В terminal
Как же с этим связан препроцессинг? Давайте разберёмся, что такое препроцессинг и для чего он нужен. В языке C есть программа-препроцессор, которая запускается автоматически перед компиляцией. Препроцессор языка C нужен для выполнения специальных команд, которые называются директивами препроцессора, которые определяют операции для выполнения, которые должны быть выполнены до компиляции. В нашем коде, написанном на языке C, есть директива
Фаза 3: компиляция
sizeof(arr_nums). Оператор sizeof принимает array и возвращает размер списка в байтах. Размер одного элемента на большинстве операционных систем составляет 4 байта, а так как в массиве 5 элементов, то 4 * 5 = 20 в итоге получим 20 байт. Мы получили размер списка 20 байт в левом операнде. Как вы можете догадаться, далее мы делим размер списка на размер первого элемента, взяв его по индексу 0. В итоге получается математическая операция 20 / 4 = 5 , результатом которой будет количество элементов в списке - 5. Для чего это нужно нам объяснит цикл for. Рассмотрим первую строку цикла for (int i=0; i < size; i++) {. Читателю должно быть сразу бросается в глаза, что мы для использования переменной индекса объявляем целочисленную переменную и присваиваем ей число 0 в int i=0;. Она нам будет необходима для взятия элемента списка по индексу. В то время как в моём примере цикла for в Python в проходе по списку я сразу получал его элемент, не используя индекс. Прилагаю строку из Python для наглядности: for num in nums_list:. Далее идёт условие i < size; после которого произойдёт выход из цикла. Для корректной работы цикла в i++ мы будем увеличивать переменную для индекса после каждого прохода цикла for. В результате мы получим числа для индекса 0, 1, 2, 3, 4 и выйдем из цикла for, когда i станет равна 5 и условие 5 < 5 не выполнится. Это довольно сильно похоже на цикл while в Python из-за выхода из цикла for по условию. В одной из следующих статей я расскажу о while в Python подробнее и сравню его с while из C. Вернёмся к нашему циклу и посмотрим на операцию в его теле sum_nums += arr_nums[i];. Оператором присвоения += складываем переменную sum_nums c числом из arr_nums[i], которое мы берём по индексу из списка. Результат присваивается переменной sum_nums. Не забываем про {} для тела цикла и ; для обозначения конца инструкции. Компилятору нужно понимать где конец инструкции для его правильной работы. В Python мы аналогично используем оператор присвоения +=, но используем значение переменной, а не берём число по индексу из списка в sum_nums += num.Фаза 2: препроцессинг
После того как мы написали программный код, мы обязательно захотим его выполнить и посмотреть как работает наша программа. Для этого мы запускаем процесс компиляции в C.
В terminal
$ gcc sum_nums.c -o sum_nums
Как же с этим связан препроцессинг? Давайте разберёмся, что такое препроцессинг и для чего он нужен. В языке C есть программа-препроцессор, которая запускается автоматически перед компиляцией. Препроцессор языка C нужен для выполнения специальных команд, которые называются директивами препроцессора, которые определяют операции для выполнения, которые должны быть выполнены до компиляции. В нашем коде, написанном на языке C, есть директива
#include <stdio.h>, в которой <stdio.h> это заголовочный файл для библиотеки, хранящий в себе функции ввода/вывода (пример printf()). Директива в языке программирования C - это инструкция для препроцессора, которая выполняется до фазы компиляции. Директива #include используется для включения библиотек. Если мыслить на Python языке, то это похоже отдалённо на то, что мы импортировали библиотеку в код целиком и теперь можем её использовать во время выполнения программы. На языке Python мы пока что ничего не будем делать ибо у него нет стадии препроцессинга, так как он не требует предварительной обработки.Фаза 3: компиляция
🔥3
После того как отработал препроцессор, что обработал нам директивы, начинается процесс компиляции в C. Сначала компилятор выполняет лексический и синтаксический анализ исходного кода, чтобы проверить на наличие ошибок. Если ошибок не обнаружено, то компилятор транслирует программу в машинный код. Машинный код — это низкоуровневый код, который может быть напрямую выполнен процессором компьютера. Он представляет собой последовательность чисел, которые являются инструкциями для процессора. Если обнаруживается ошибка, то компилятор выводит сообщение с ошибкой компиляции. Я специально уберу индекс из кода
В terminal
Давайте разберёмся в ошибке. Мы видим, что ошибка в функции
Фаза 4: компоновка
Компоновка (или линковка) в языке C - это процесс, в котором компоновщик собирает различные модули кода, такие как исходные файлы и библиотеки, в один исполняемый файл. Процесс компоновки делится на следующие шаги:
1. Каждый исходный файл C компилируется в отдельный объектный файл (обычно с расширением
2. Компоновщик анализирует объектные файлы и библиотеки, чтобы определить, какие внешние ссылки (например, функции и глобальные переменные, которые определены в других файлах) необходимо разрешить;
3. Компоновщик включает в исполняемый файл библиотеки, необходимые для выполнения программы, и разрешает ссылки на функции и данные, которые определены в этих библиотеках;
4. Если в программе используются ресурсы, такие как изображения или звуки, компоновщик также включает их в исполняемый файл;
5. Наконец, компоновщик генерирует исполняемый файл, который содержит все необходимые машинные инструкции, данные и ресурсы, собранные из объектных файлов и библиотек;
После процесса компоновки у нас с вами получился исполняемый файл
Откроем исполняемый файл
Перед вами первые 10 строк файла
Каждая строка это 64-битное значение в шестнадцатеричной системе счисления. Чтобы понять содержимое файла, нужно знать архитектуру процессора и много чего ещё. Возможно, я затрону эту тему в будущем, но пока вам достаточно того что это машинный код, который выполняет процессор компьютера.
sum_nums += arr_nums[]; чтобы показать как выглядит ошибка при компиляции.В terminal
sum_nums.c: In function ‘main’:
sum_nums.c:9:30: error: expected expression before ‘]’ token
9 | sum_nums += arr_nums[];
| ^
Давайте разберёмся в ошибке. Мы видим, что ошибка в функции
main, в строке 9, видим саму строку с ошибкой error: expected expression before ‘]’ token. Ошибка нам говорит, что компилятор ожидает некое выражение перед закрытием ], что нам намекает на допущенную ошибку в синтаксисе и мы забыли что-то написать. В нашем случае мы не указали переменную i, которая отвечает за индекс. Мы должны были взять элемент по индексу из списка. Я исправлю данный код и продолжу процесс дальше. Машинный код пока рано показывать на данной стадии. Что же касается языка Python, то у него нет этапа компиляции так как это не компилируемый язык. Вместо этого у него есть процесс интерпретации, до которого мы дойдём, когда, наконец, получим исходный файл языка С чтобы сравнить процесс запуска программ.Фаза 4: компоновка
Компоновка (или линковка) в языке C - это процесс, в котором компоновщик собирает различные модули кода, такие как исходные файлы и библиотеки, в один исполняемый файл. Процесс компоновки делится на следующие шаги:
1. Каждый исходный файл C компилируется в отдельный объектный файл (обычно с расширением
.o или .obj), который содержит машинный код и информацию для компоновщика;2. Компоновщик анализирует объектные файлы и библиотеки, чтобы определить, какие внешние ссылки (например, функции и глобальные переменные, которые определены в других файлах) необходимо разрешить;
3. Компоновщик включает в исполняемый файл библиотеки, необходимые для выполнения программы, и разрешает ссылки на функции и данные, которые определены в этих библиотеках;
4. Если в программе используются ресурсы, такие как изображения или звуки, компоновщик также включает их в исполняемый файл;
5. Наконец, компоновщик генерирует исполняемый файл, который содержит все необходимые машинные инструкции, данные и ресурсы, собранные из объектных файлов и библиотек;
После процесса компоновки у нас с вами получился исполняемый файл
sum_nums. Давайте посмотрим как выглядит машинный код у него внутри.Откроем исполняемый файл
sum_nums с помощью sublime text7f45 4c46 0201 0100 0000 0000 0000 0000
0300 3e00 0100 0000 8010 0000 0000 0000
4000 0000 0000 0000 d036 0000 0000 0000
0000 0000 4000 3800 0d00 4000 1f00 1e00
0600 0000 0400 0000 4000 0000 0000 0000
4000 0000 0000 0000 4000 0000 0000 0000
d802 0000 0000 0000 d802 0000 0000 0000
0800 0000 0000 0000 0300 0000 0400 0000
1803 0000 0000 0000 1803 0000 0000 0000
1803 0000 0000 0000 1c00 0000 0000 0000
...
Перед вами первые 10 строк файла
sum_nums из 1002. Естественно, я не мог впихнуть все 1002 строки в данную статью поэтому сократил вывод =)Каждая строка это 64-битное значение в шестнадцатеричной системе счисления. Чтобы понять содержимое файла, нужно знать архитектуру процессора и много чего ещё. Возможно, я затрону эту тему в будущем, но пока вам достаточно того что это машинный код, который выполняет процессор компьютера.
🔥2👍1
В языке Python нет процесса компоновки так как это не компилируемый язык и не требуется генерировать исполняемый файл как в языке C. Однако стоит отметить, что есть такие механизмы как Cython и ctypes. Cython - статический компилятор, который позволяет языку Python компилировать код на C и C++ и вызывать его из Python3. Ctypes - это библиотека для Python, которая позволяет Python взаимодействовать с C кодом, что позволяет Python работать на более низком уровне. Правда, это касается взаимодействия языков C и Python. Это довольно интересная тема и в последующих статьях я обязательно её затрону. Сам же Python по прежнему не нужно компилировать и компоновать. Это касается только C кода, который можно использовать в коде Python.
Фаза 5: загрузка
Для того чтобы программу можно было запустить, её сначала нужно загрузить в оперативную память. В языке C эту операцию выполняет загрузчик, который читает выполняемый образ с диска и копирует его в оперативную память. Также загрузчик производит загрузку необходимых разделяемых библиотек. В языке Python программный код загружается в оперативную память полностью для того чтобы выполниться потом построчно. На этом этапе, если в коде обнаружится ошибка, то программа будет прервана. Теперь самое время запустить наши программы на обоих языках, так как выйти на эту фазу невозможно без запуска программы.
В terminal
В terminal
Фаза 6: выполнение
Наконец, мы дошли до финальной фазы - выполнение кода. На этой фазе компьютер выполняет программу, инструкция за инструкцией в языке C. Давайте посмотрим на вывод программы у программы на языке C.
В terminal
Мы видим, что программа на языке C отработала как нужно. Только вот прежде чем я расскажу, что произойдёт с программой на Python, вас будет ждать небольшой сюрприз с выполнением программы.
В terminal
До этого мы запускали программы на Python из IDE и не испытывали проблем с запуском программ. Сейчас мы видим, что у нас нет прав на файл. Разрешим права на него.
В terminal
Попробуем запустить программу после того как мы выдали права на выполнение файла для всех пользователей.
В terminal
Почему вместо привычного вывода он выводит эти странные предупреждения, ведь у нас нет ошибок в коде? Всё очень просто - это происходит потому что в нашем файле
Давайте запустим нашу программу после изменений и посмотрим на результат её выполнения.
Фаза 5: загрузка
Для того чтобы программу можно было запустить, её сначала нужно загрузить в оперативную память. В языке C эту операцию выполняет загрузчик, который читает выполняемый образ с диска и копирует его в оперативную память. Также загрузчик производит загрузку необходимых разделяемых библиотек. В языке Python программный код загружается в оперативную память полностью для того чтобы выполниться потом построчно. На этом этапе, если в коде обнаружится ошибка, то программа будет прервана. Теперь самое время запустить наши программы на обоих языках, так как выйти на эту фазу невозможно без запуска программы.
В terminal
$ ./sum_nums
В terminal
$ ./sum_nums.py
Фаза 6: выполнение
Наконец, мы дошли до финальной фазы - выполнение кода. На этой фазе компьютер выполняет программу, инструкция за инструкцией в языке C. Давайте посмотрим на вывод программы у программы на языке C.
В terminal
Сумма чисел списка = 78
Мы видим, что программа на языке C отработала как нужно. Только вот прежде чем я расскажу, что произойдёт с программой на Python, вас будет ждать небольшой сюрприз с выполнением программы.
В terminal
bash: ./sum_nums.py: Отказано в доступе
До этого мы запускали программы на Python из IDE и не испытывали проблем с запуском программ. Сейчас мы видим, что у нас нет прав на файл. Разрешим права на него.
В terminal
chmod +x sum_nums.py
Попробуем запустить программу после того как мы выдали права на выполнение файла для всех пользователей.
В terminal
$ ./sum_nums.py
./sum_nums.py: строка 1: nums_list: команда не найдена
./sum_nums.py: строка 2: sum_nums: команда не найдена
./sum_nums.py: строка 5: синтаксическая ошибка рядом с неожиданным маркером «sum_nums»
./sum_nums.py: строка 5: ` sum_nums += num'
Почему вместо привычного вывода он выводит эти странные предупреждения, ведь у нас нет ошибок в коде? Всё очень просто - это происходит потому что в нашем файле
sum_nums.py нет строки, которая бы указывала нам на интерпретатор Python. В Debian или Ubuntu она пытается выполниться как скрипт shell. Именно поэтому мы видим вывод неких ошибок при запуске. Поправим это, добавив на первую строчку кода #!/usr/bin/env python3. Строка #!/usr/bin/env python3 называется шебанг (shebang), которая указывает путь до интерпретатора Python. Таким образом в программе будет информация о нахождении интерпретатора Python, к которому следует обратиться для выполнения программы. Наш код теперь будет выглядеть вот так.#!/usr/bin/env python3
nums_list = [1, 3, 4, 50, 20]
sum_nums = 0
for num in nums_list:
sum_nums += num
print(f'Сумма чисел списка = {sum_nums}')
Давайте запустим нашу программу после изменений и посмотрим на результат её выполнения.
$ ./sum_nums.py
Сумма чисел списка = 78
🔥4
Мы видим, что программа на Python выполнилась успешно, но как же это происходит в итоге?
Процесс загрузки и интерпретации кода Python включает в себя несколько этапов, которые происходят
на лету:
1. Python считывает код построчно, интерпретирует его и преобразует в байт-код;
2. Интерпретатор Python компилирует байт-код в машинный код для выполнения;
3. Машинный код выполняется на процессоре;
Тут мы увидели новое для себя слово байт-код. Что же такое байт-код? Байт-код в Python - это промежуточное представление исходного кода Python, которое интерпретатор Python использует для выполнения программы. Когда вы запускаете Python-скрипт, компилятор Python преобразует исходный код в байт-код, который затем интерпретируется и выполняется виртуальной машиной Python. Этот процесс позволяет Python быть интерпретируемым языком, что делает его более портативным и удобным для разработчиков, поскольку не требуется компиляция исходного кода в машинный код для каждой целевой платформы.
Байт-код Python хранится в файлах с расширением
Использование байт-кода имеет несколько преимуществ:
1. Байт-код может быть быстрее загружен и выполнен, поскольку он уже был скомпилирован;
2. Поскольку байт-код не зависит от конкретной архитектуры процессора, Python-программы могут быть легко перенесены между различными платформами;
3. Байт-код может быть защищен от прямого чтения исходного кода, что может быть полезно для скрытия логики приложения;
Пару слов о виртуальной машине Python, о которой я упомянул выше. Виртуальная машина в Python - это компонент, который интерпретирует байт-код Python и выполняет его. В контексте Python, виртуальная машина - это часть интерпретатора Python, которая преобразует байт-код в исполняемые инструкции.
Поздравляю, мы прошли все фазы от создания программы в ide до её выполнения на процессоре и сравнили фазы на Python и C :)
Выше в данной статье, рассказывая о цикле
Заключение
1. Узнали про отличия цикла
2. Узнали тонкости запуска скрипта на Python;
3. Прошли и сравнили все фазы: от создания программы в IDE до её выполнения на процессоре на Python и C;
Файлы к посту, можно получить в боте по коду: 591950
Пост на сайте
Поддержать проект
#Python #Сравнение_Python_и_C #Компилятор #C #Цикл #Интерпретатор #for
Процесс загрузки и интерпретации кода Python включает в себя несколько этапов, которые происходят
на лету:
1. Python считывает код построчно, интерпретирует его и преобразует в байт-код;
2. Интерпретатор Python компилирует байт-код в машинный код для выполнения;
3. Машинный код выполняется на процессоре;
Тут мы увидели новое для себя слово байт-код. Что же такое байт-код? Байт-код в Python - это промежуточное представление исходного кода Python, которое интерпретатор Python использует для выполнения программы. Когда вы запускаете Python-скрипт, компилятор Python преобразует исходный код в байт-код, который затем интерпретируется и выполняется виртуальной машиной Python. Этот процесс позволяет Python быть интерпретируемым языком, что делает его более портативным и удобным для разработчиков, поскольку не требуется компиляция исходного кода в машинный код для каждой целевой платформы.
Байт-код Python хранится в файлах с расширением
.pyc, которые создаются автоматически при первом запуске скрипта. Эти файлы содержат байт-код, который может быть быстрее загружен и выполнен, поскольку он уже был скомпилирован. Файлы.pyc обычно находятся в подкаталоге __pycache__ рядом с исходными файлами .py.Использование байт-кода имеет несколько преимуществ:
1. Байт-код может быть быстрее загружен и выполнен, поскольку он уже был скомпилирован;
2. Поскольку байт-код не зависит от конкретной архитектуры процессора, Python-программы могут быть легко перенесены между различными платформами;
3. Байт-код может быть защищен от прямого чтения исходного кода, что может быть полезно для скрытия логики приложения;
Пару слов о виртуальной машине Python, о которой я упомянул выше. Виртуальная машина в Python - это компонент, который интерпретирует байт-код Python и выполняет его. В контексте Python, виртуальная машина - это часть интерпретатора Python, которая преобразует байт-код в исполняемые инструкции.
Поздравляю, мы прошли все фазы от создания программы в ide до её выполнения на процессоре и сравнили фазы на Python и C :)
Выше в данной статье, рассказывая о цикле
for, я упомянул о цикле while, пообещав вам рассказать о нём. Раз в данной статье я начал с циклов for, то в следующей статье я продолжу тему циклов. Расскажу вам, чем отличаются цикл while в C от цикла while в Python. Расскажу, для чего эти циклы нужны и покажу их применение на интересной задаче. Дальше будет ещё интереснее :)Заключение
1. Узнали про отличия цикла
for в C от цикла for в Python;2. Узнали тонкости запуска скрипта на Python;
3. Прошли и сравнили все фазы: от создания программы в IDE до её выполнения на процессоре на Python и C;
Файлы к посту, можно получить в боте по коду: 591950
Пост на сайте
Поддержать проект
#Python #Сравнение_Python_и_C #Компилятор #C #Цикл #Интерпретатор #for
🔥3🤯3
Добрый вечер и добро пожаловать в пятницу!
Настало время для заслуженного отдыха после трудовой недели. Ничто не сравнится с уютом дома, чашечкой горячего чая или попкорном в руках, ведь сегодня - идеальный вечер для просмотра фильма. Пусть этот вечер будет наполнен теплом, эмоциями и приятными впечатлениями от просмотра.
В прошлую пятницу мы смотрели последнюю работу оскароносного Гения - Нолана, а в этот раз смотрим его лучший, на мой взгляд, фильм.
Фильм: Начало
Год: 2010
Кобб – талантливый вор, лучший из лучших в опасном искусстве извлечения: он крадет ценные секреты из глубин подсознания во время сна, когда человеческий разум наиболее уязвим. Редкие способности Кобба сделали его ценным игроком в привычном к предательству мире промышленного шпионажа, но они же превратили его в извечного беглеца и лишили всего, что он когда-либо любил.
https://www.sspoisk.ru/film/447301/
Приятного просмотра
Настало время для заслуженного отдыха после трудовой недели. Ничто не сравнится с уютом дома, чашечкой горячего чая или попкорном в руках, ведь сегодня - идеальный вечер для просмотра фильма. Пусть этот вечер будет наполнен теплом, эмоциями и приятными впечатлениями от просмотра.
В прошлую пятницу мы смотрели последнюю работу оскароносного Гения - Нолана, а в этот раз смотрим его лучший, на мой взгляд, фильм.
Фильм: Начало
Год: 2010
Кобб – талантливый вор, лучший из лучших в опасном искусстве извлечения: он крадет ценные секреты из глубин подсознания во время сна, когда человеческий разум наиболее уязвим. Редкие способности Кобба сделали его ценным игроком в привычном к предательству мире промышленного шпионажа, но они же превратили его в извечного беглеца и лишили всего, что он когда-либо любил.
https://www.sspoisk.ru/film/447301/
Приятного просмотра
🔥6
Комментарии
Автор: Иван Ашихмин
Приветствую.
Решил освещать нововведения на сайте отдельными постами и начать с комментариев.
На сайте добавлены комментарии к постам.
Писать комментарии могут только зарегистрированные пользователи.
Автор комментария может его отредактировать или удалить при желании.
Не стесняйтесь писать комментарии с вопросами, предложениями, а также критику работы самих комментариев.
Пост на сайте
Поддержать проект
#новости #Код_на_салфетке #посты #комментарии
Автор: Иван Ашихмин
Приветствую.
Решил освещать нововведения на сайте отдельными постами и начать с комментариев.
На сайте добавлены комментарии к постам.
Писать комментарии могут только зарегистрированные пользователи.
Автор комментария может его отредактировать или удалить при желании.
Не стесняйтесь писать комментарии с вопросами, предложениями, а также критику работы самих комментариев.
Пост на сайте
Поддержать проект
#новости #Код_на_салфетке #посты #комментарии
🔥4👍1
Что выведет код с изображения ниже?
Anonymous Quiz
48%
True True
17%
True False
2%
False True
33%
False False
Forwarded from Заметки на салфетке
Всем привет)
Стрима сегодня не будет потому, что я не придумал тему)
В чате кота появилось несколько идей и чтобы они не потерялись, прошу продублировать их в комментариях к этому посту.
В течении недели буду собирать идеи и будем выбирать, что будем делать в следующее воскресенье.
Стрима сегодня не будет потому, что я не придумал тему)
В чате кота появилось несколько идей и чтобы они не потерялись, прошу продублировать их в комментариях к этому посту.
В течении недели буду собирать идеи и будем выбирать, что будем делать в следующее воскресенье.
🔥2😁1
Вчера мы опубликовали задачу, которая отсылает нас ко второму посту Андрея "== != is". Судя по количеству верных ответов, а их всего 15% или 6 человек из 39-ти, без пояснений не обойтись.
Код задачи:
Разберём задчу.
Создаём четыре меременные -
Затем, вызвав функцию
1.
2.
Что пошло не так?
В результате после проведения математических операций, у нас будет следующие проверки:
- 200 это 200?
- 300 это 300?
49% участников ответили "Да!" и оказались не правы.
"Соль" заключается в способе хранения Python'ом чисел в оперативной памяти. Если говорить максимально просто, то числа от 0 до 255 хранятся в "зарезервированной" памяти, в случае с числами больше 255, каждый раз создаётся своя ячейка.
Проверить это можно следующим образом:
В результате получим следующий вывод:
Как видим, в первых двух строках
Заключение.
Как видим, все не так просто в Python с хранением данных в памяти. Стоит помнить и понимать работу, дабы быть готовым к неожидонностям.
Настоятельно рекомендую прочитать статью Андрея, для закрепления - "== != is"
Код задачи:
a = 200
b = 20
c = 300
d = 30
print(a is b * 10, c is d * 10)
Разберём задчу.
Создаём четыре меременные -
a, b, c и d. В каждую переменную определяем число.Затем, вызвав функцию
print() выводим на экран два выражения:1.
a is b * 10 - Проверяем, что число в переменной a это число из переменной b умноженное на 10.2.
c is d * 10 - Проверяем, что число в переменной c это число из переменной d умноженное на 10.Что пошло не так?
В результате после проведения математических операций, у нас будет следующие проверки:
- 200 это 200?
- 300 это 300?
49% участников ответили "Да!" и оказались не правы.
"Соль" заключается в способе хранения Python'ом чисел в оперативной памяти. Если говорить максимально просто, то числа от 0 до 255 хранятся в "зарезервированной" памяти, в случае с числами больше 255, каждый раз создаётся своя ячейка.
Проверить это можно следующим образом:
a = 200
b = 20
c = 300
d = 30
print(f"{id(a)=}\n{id(b * 10)=}\n{id(c)=}\n{id(d * 10)=}")
В результате получим следующий вывод:
id(a)=140716981156872
id(b * 10)=140716981156872
id(c)=2349489175568
id(d * 10)=2349492150192
Как видим, в первых двух строках
id совпадает, а вторых двух - нет.Заключение.
Как видим, все не так просто в Python с хранением данных в памяти. Стоит помнить и понимать работу, дабы быть готовым к неожидонностям.
Настоятельно рекомендую прочитать статью Андрея, для закрепления - "== != is"
🔥13👍2