Все по делу, спасибо. Если вдруг кто не в курсе, то комментарий к функции лучше писать в тройных кавычках в теле функции, тогда он появится в подсказке при наведении курсора на функцию
1. Думаем над именами функций и классов. Код пишется один раз, а читается постоянно. 2. Type annotations для функций и внимательно отслеживаем несоответствия по типам данных на уровне проекта. Очень много херни позволяет отловить с минимальной задержкой. 3. Докстринги, в которых описываемых всё, что функция принципиально делает. Комментарии - только там, где надо пояснить какое-то неочевидное решение, из-за, например, изврата бизнес-логики. 4. from xxx import * --- должен вообще не пройти код ревью коллег и не попасть в мастер. 5. В числе ревьюеров должен быть маньяк идеи чистого кода, нам повезло, у нас их два.
Насчёт неочевидных имён функций согласен на все 200%, а вот насчёт требования к уникальности названий категорически против. Кто сделал import *, тот сам дурак. А если в двух разных модулях функции выполняют логически одно и то же, но по-разному, то почему-бы и не назвать их идентично.
Я бы добавил еще про ОПП Мы должны использовать классы осознанно, не просто для того что б имена функций были более краткими и понятными, а с какой то целью например хранение состояния (это было сказано, но как дополнительный бонус) или возможности полиморфизма и прочие плюсы классов просто использовать функции что б сократить имена классов и тд - это не правильно
несколько курсов на степике прошел по питону, видел как люди писали в функциях аннотацию, но не понимал для чего конкретно это нужно, теперь разобрался; начал смотреть твой канал и ты мне очень помогаешь в понимании этого языка, спасибо тебе, твой канал один из лучших по питону!
6:28 лишним плюсом реализации методов класса вместо функций будет полиморфизм, который станет, доступным для методов. Об уникальности методов нужно будет думать только в рамках класса, а не всей системы. К тому же, созданный класс задаст контекст использования методов, будет проще контролировать инпут/аутпут.
В примере про скорс, с добавлением числа в массиву, меняется аргумент, чего в чистых функциях быть не должно, поэтому и возникло затруднение при вызовах. Должен был создаваться новый массив и возвращать результат. В JS это понимание очень часто играет.
3 совета очевидны (овер или недокоммент, нет аннотаций, плохое название функции). Как предложение, можно добавить объяснение поч плохо сохранять лямбды в переменные, использовать простые функции в абстракциях (для новичков может быть непонятно), почему перегрузка функций typing.overload с одним и тем же параметром с разным названием вне .pyi файла вообще нежелательно (Моё мнение).
3:46 Развёрнутые комментарии лучше всего делать внутри функции для объяснения смысла алгоритма и всяких не очевидных "подводных" особенностей. А короткие комментарии должны быть превращены в название функции, в которую войдёт комментируемый кусок кода.
Первая рекомендация про именование хорошая, хотя не нова (тут следует сослаться на того же Макконнелла с его книгой "Совершенный код"). Остальное - nah... Насчёт методов, которые предлагается в класс обернуть - там сразу value и values лишние, потому что не добавляют ничего к пониманию сути функций (понятное дело что речь про значения, а не неопределённости или незначимости). Да и вообще лучше указывать что на что делится, потому метод должен зваться так, чтобы код получился вроде с = a.divideBy(b), иначе будет не понятно то ли a на b делится, то ли наоборот. Да и попытка создать класс на пустом месте - плохая идея, иначе следовало бы отказаться от выражений вида a*b, a + b, a % b и так далее и всё следовало бы их писать как a.mod(b), a.multiplyBy(b), a.divideBy(b) и т.д.. Раз мы все так не делаем, то следует предположить, что идея плохая и классы придуманы для другого (а такое "нововведение" лишь без причины усложнит код). Насчёт передачи по ссылке параметра по-умолчанию - я бы это охарактеризовал как баг питона. Согласен, работая с питоном об этом следует знать и в этом плане респект автору (лично я на питоне не пишу, потому для меня это было открытием). Но это значит, что в питоне не скалярные параметры с заданным значением по-умолчанию использовать нельзя, потому что это по определению функция грязная, которая обязательно породит непредсказуемое поведение. Потому часть про "если вы знаете как, то можете это использовать" из разряда вредных советов.
Могу про лямбду добавить: есть вот люди, которые постоянно везде суют лямбду, т.е. x = lambda y: y ** 2 print(x(5)) Сделайте вид, что тут что-то сложное. И вот, часто замечал, что многие любят делать огромные строки, где тупа одна лямбда как какая-то функция Это нарушение PEP8 про длину строки и ещё одно нарушение, что лямбда используется неправильно (даже в пепе есть (!!)) Правильно лямбда используется в таких моментах: print(sorted(["c", "b", "a"], key=lambda x: x[0].lower())) # prints: ['a', 'b', 'c'] Это просто пример, но думаю суть ясна. Вооооооооооооооооот, да
def - создаёт объект класса function, которому назначаются поля. Если мы не переопределяем эти поля при вызове функции, естественно мы работаем со значениями, которые уже определены для полей. За счёт этого, как я понимаю, работают всякие функции-генераторы. Да, это поведение не вполне очевидно, если мыслить в рамках процедурного программирования, к сожалению.
На питоне пишу неделю. До этого практически ничего не кодил . Какой прием успел вывести: Сперва высматриваю в задаче задачки поменьше. То есть, пишу мини библиотеку методов под одну задачу. Нафига: а чтоб не запутаться. Это как собирать дом готовыми модулями. Конечно не все действия так заранее прописываю, только более или менее типовые.
Я тут в общем, пишу функцию и тут ты! Спасибо, обязательно посмотрю позже! Я проверяю инстансами, и зачастую люблю писать в одну строку так: ('True' if mesg == 'hi' else 'False'), [i for i in mesg....]
@@MagMigo 1.С булами затупил немного когда писал это, а так, я делаю реальными булами без " " 2.Нет, у меня нет проблем с логикой, я не сказал ещё если в друг мне нужно по листу пройтись или написть что-то если Тру или Фолз Примерно так, выглядит моя функция: def hello(text): if not isinstance(text, list): raise ... return [i for i in text if i == 'Hey']
@@scrooge6603 Уже в этом случае нет проблем, но если ты будешь делать так def hello(text: str) -> bool: # Допустим, тебе будет нужна функция, где тебе надо чтоб возвращался только буль return isinstance(str, text) Под алгебра-логикой я это имел ввиду.
3:12 Вы хоть сами поняли, что написали, может быть вы имели from lib import * : в таком случае все функции и классы запишутся в основной модуль А если import lib : то к функциям и классам придётся обращаться через имя библитеки и уникальность уже не обязательна
Видео очень хорошее, но можно было бы сюда сразу теории докинуть, так как в видео упоминается, и про Single responsibility principle , и про DRY, и про KISS
7:04 а что тут не так? вполне может быть оберткой для трубы, а далее уже по логике но название и действия должны как-то матчится 2:06 это же язык динамической типизации зачем резать на входе-то? Массивы же разные могут быть, тут или имя менять или логику внутри функции.
Всё правильно. Если даже тебе нет дела до тех, кто согнал тебя с работы, и теперь поддерживает твой код, позаботься о себе драгоценном. Понять собственный код, который ты писал год назад, особенно в крупном проекте, на пару сотен питон-файлов, очень не просто. Надо осмысленно называть модули, функции, классы, и даже соорудить простейший сервер с документацией и поиском по ней.
Вместо, а даже лучше вместе с комментариями хорошо использовать докстринги. Если не хочется лезть в модуль и вычитывать там функционал функции, просто пишешь хельп(), и он у тебя на ладони. Тоесть в докстринги пишем комментарии по использованию, в обычные коменты - по реализации
Я наверно спрошу какую-то глупость... Я понял, что функция append_score где-то там внутри хранит значение аргумента по умолчанию - список по умолчанию scores - и при каждом вызове функции без указания аргумента по умолчанию этот "список по умолчанию" дополняется. Вопрос - как добраться до этого "списка по умолчанию" извне этой функции? Или инкапсуляция этого не позволит? То есть - вызвали функцию без аругмента по умолчанию, она внутри себя создала переменную типа указатель (с простым числом это не прокатывает), этот указатель указывает на одну и ту же область памяти, и при каждом вызове функции без аргумента по умолчанию содержимое этой области памяти ("список по умолчанию") последовательно модифицируется. И этот "список по умолчанию" хранится до конца работы пограммы, но до него никак не добрешься? Я примерно предполагаю ответ - доступ к этому "списку по умолчанию" должен быть предусмотрен логикой программы, в данном примере такого доступа нет - ну и доступа нет. Но все равно страннно. В этом есть какой-то полезный смысл, или это побочный эффект архитектуры Питона?
Насчет args, kwargs не совсем согласен, часто использую, особенно когда нужно наследовать какой-либо класс и добавить в него свой функционал, не изменяя уже существующий, но пример из видео, да, согласен - ужас)
Найс, выучил Python, теперь иди учи английский, потому что циклы циклами, а названия за тебя никто не придумает :D Спасибо за полезный материал! Но не проще ли просто писать коммент к функции и не париться с придумываем названий, особенно когда у тебя в одной проге 100500 этих функций и уже фантазия закончилась :D
Здравствуйте, одна маленькая поправочка: Вы здесь имеете в виду языки со _статической типизацией_, где типы переменных и выражений объявляются программистом или выводятся компилятором. Определение же "строгой/слабой" типизации зависит от сообщества, в котором употребляется. Иногда термин "строгая типизация" используется как синоним статической типизации (как в Вашем комментарии), но есть также и такое (на мой взгляд, лучшее) определение: язык является "строго типизированным", если он не позволяет нарушить собственные абстракции (такие, как типы данных) (по крайней мере, в "безопасных" контекстах). В таком понимании язык Python является строго типизированным языком с динамической типизацией, а C++ является слабо типизированным языком со статической типизацией (т.е., понятия "строгости" и "времени" типизации ортогональны). Просто мои пять копеек, думаю, кому-то будет полезно знать о таких альтернативных определениях ;-)
@@zproger Да, это понятно. Просто точно такие же темы обсуждаются в других языках программирования и точно так же не указывается что это общие правила программирования. Но понравилось чьё-то высказывание: "Самое главное и самое сложное в программировании- правильно назвать функцию".
Пожалуйста не юзайте списочные выражение с лямбдой на лямбде заправленной условиями и распаковкой. Это буквально криг души и каждый раз хочется орать когда видишь такой код
Во второй ошибке (про уникальность имён функций и конфликт с другими либами) откровенно говоря бред. По вашей логике, человек при подключении библиотек должен прочитать абсолютно все ее функции и их имена, чтобы не повториться, вместо того чтобы просто нормально импортировать. Да и вообще можно было приличия ради добавить, как решить проблему ссылочного типа в аргументе
IDE подскажет если ты перезапишешь функцию из модуля это раз. Как правило в модулях просто функций нет, есть только методы внутри класса это два. Скорее речь шла о ваших собственных модулях. Не используйте wildcard import это три)
Можете порекомендовать ресурс для изучения Python, может книжку какую-то? Оплачивать обучение на данный момент не очень хочу, как минимум потому что мне 15 лет. Смотрел уже 3 бесплатных курса на ютубе, но хочу продвигаться дальше.
Sololearn, Проект Эйлера (первые 35 упражнений, дальше больше математика. С какого-то момента сложность резко возрастает, так-что несколько дней на упражнение станет нормой) и если совсем ноль в программировании "Грокаем алгоритмы". Когда добрался до них показались примитивными, но может просто забыл как учился ездить на велосипеде. Дальше гугл, свой проект и возможно Лутц. Лутц это не учебник, а скорее справочник. Читать только чтобы убедиться что ничего не пропустил, и то через год-полтора. Советую так же уже сейчас учить слепую печать. Полотенце на клавиатуру, указательные на пупырки и 30 минут в день месяц-полтора. После такой базы скорость печати вернется на прежний уровень и практику можно будет набивать на бытовом печатании. Сам проходил в 14, когда даже не думал о программировании. Зачем? В темноте не было видно клавиатуры :D Ах да, нулевой язык программирования - английский. Любой интернетный текст в зубы (Литературный носители переусложняют) и переводим гугл-переводчиком слово за словом примечая частые. Первые 50 часов ничего в голове задерживаться не будет, и это нормально. И не стоит гнаться за "100%" английским. Его не бывает. Игровой, ютуберный, программисткий, математический английские - выбери кусочки и все. По своему опыту так же скажу, что чтение можно выучить в вакууме. Произношение, слух и разговор можно отложить лет до 20. Так же для мотивации идеально подойдут уроки. В 9 классе за вами как раз перестанут следить, если не уже. Ну и бонус за простыню. Написано так ясно, что переводчик переводит как с русского на русский: betterexplained.com/articles/a-visual-intuitive-guide-to-imaginary-numbers/
А ещё, когда опорожняетесь- снимайте штанишки. Для кого этот мануал? Я без негатива к автору, просто интересно- есть люди, которые изучают синтаксис/продвинутый уровень и для них это не очевидно?
Все по делу, спасибо. Если вдруг кто не в курсе, то комментарий к функции лучше писать в тройных кавычках в теле функции, тогда он появится в подсказке при наведении курсора на функцию
Спасибо за дополнение к видео, это хороший совет
Не понимаю, почему ролик выходит то для новичков, то для тех, кто уже смешарик. Это БАЗА
Бывает =)
Лайк за смешариков 👍🏿
Базированный гигачад
Сколько часов в шарараме?
@@killuar02948 лет умножить на 8760 часов = 70080
1. Думаем над именами функций и классов. Код пишется один раз, а читается постоянно.
2. Type annotations для функций и внимательно отслеживаем несоответствия по типам данных на уровне проекта. Очень много херни позволяет отловить с минимальной задержкой.
3. Докстринги, в которых описываемых всё, что функция принципиально делает. Комментарии - только там, где надо пояснить какое-то неочевидное решение, из-за, например, изврата бизнес-логики.
4. from xxx import * --- должен вообще не пройти код ревью коллег и не попасть в мастер.
5. В числе ревьюеров должен быть маньяк идеи чистого кода, нам повезло, у нас их два.
Маньяки чистого кода это хорошо
Со всеми пунктами согласен
Насчёт неочевидных имён функций согласен на все 200%, а вот насчёт требования к уникальности названий категорически против. Кто сделал import *, тот сам дурак. А если в двух разных модулях функции выполняют логически одно и то же, но по-разному, то почему-бы и не назвать их идентично.
Так речь идёт не про разные модули, в разных модулях эти функции не будут пересекаться.
Я бы добавил еще про ОПП
Мы должны использовать классы осознанно, не просто для того что б имена функций были более краткими и понятными, а с какой то целью
например хранение состояния (это было сказано, но как дополнительный бонус) или возможности полиморфизма и прочие плюсы классов
просто использовать функции что б сократить имена классов и тд - это не правильно
import * нужен только в tkinter
Смотрел это видео и одновременно делал оператор "в" в своем языке :P
несколько курсов на степике прошел по питону, видел как люди писали в функциях аннотацию, но не понимал для чего конкретно это нужно, теперь разобрался; начал смотреть твой канал и ты мне очень помогаешь в понимании этого языка, спасибо тебе, твой канал один из лучших по питону!
Молодец объяснил чистый код и принципы солид), а про scores это жесть, поэтому лучше писать в ооп стиле
Спасибо большое дружище, очень крутой и познавательный видос!!!
Спасибо =)
Очень интересно и информативно, жду следущих видео)
Благодарю :)
6:28 лишним плюсом реализации методов класса вместо функций будет полиморфизм, который станет, доступным для методов. Об уникальности методов нужно будет думать только в рамках класса, а не всей системы. К тому же, созданный класс задаст контекст использования методов, будет проще контролировать инпут/аутпут.
append_score(score, scores=[]) - имба вообще, не знал о таком, спасибо!
В примере про скорс, с добавлением числа в массиву, меняется аргумент, чего в чистых функциях быть не должно, поэтому и возникло затруднение при вызовах. Должен был создаваться новый массив и возвращать результат. В JS это понимание очень часто играет.
Импорт через звездочку просто надо себе запретить. Оооочень много проблем снимает. А в удобстве почти не теряешь с современными редакторами.
Согласен
Спасибо!Информативно и полезно!
Благодарю
3 совета очевидны (овер или недокоммент, нет аннотаций, плохое название функции). Как предложение, можно добавить объяснение поч плохо сохранять лямбды в переменные, использовать простые функции в абстракциях (для новичков может быть непонятно), почему перегрузка функций typing.overload с одним и тем же параметром с разным названием вне .pyi файла вообще нежелательно (Моё мнение).
Спасибо за информативный и понятный контент)
Рад что понравилось
Спасибо за видео, структурированно и понятно
Рад что понравилось
Да, интересно тут)) Если можно голосовать за тему для выпуска, то голосую за борьбу с круговыми импортами)
Хорошая идея, спасибо
3:46 Развёрнутые комментарии лучше всего делать внутри функции для объяснения смысла алгоритма и всяких не очевидных "подводных" особенностей. А короткие комментарии должны быть превращены в название функции, в которую войдёт комментируемый кусок кода.
Первая рекомендация про именование хорошая, хотя не нова (тут следует сослаться на того же Макконнелла с его книгой "Совершенный код"). Остальное - nah...
Насчёт методов, которые предлагается в класс обернуть - там сразу value и values лишние, потому что не добавляют ничего к пониманию сути функций (понятное дело что речь про значения, а не неопределённости или незначимости). Да и вообще лучше указывать что на что делится, потому метод должен зваться так, чтобы код получился вроде с = a.divideBy(b), иначе будет не понятно то ли a на b делится, то ли наоборот. Да и попытка создать класс на пустом месте - плохая идея, иначе следовало бы отказаться от выражений вида a*b, a + b, a % b и так далее и всё следовало бы их писать как a.mod(b), a.multiplyBy(b), a.divideBy(b) и т.д.. Раз мы все так не делаем, то следует предположить, что идея плохая и классы придуманы для другого (а такое "нововведение" лишь без причины усложнит код).
Насчёт передачи по ссылке параметра по-умолчанию - я бы это охарактеризовал как баг питона. Согласен, работая с питоном об этом следует знать и в этом плане респект автору (лично я на питоне не пишу, потому для меня это было открытием). Но это значит, что в питоне не скалярные параметры с заданным значением по-умолчанию использовать нельзя, потому что это по определению функция грязная, которая обязательно породит непредсказуемое поведение. Потому часть про "если вы знаете как, то можете это использовать" из разряда вредных советов.
За видео спасибо, уже так сказать опытная котлета но на одном из первых собесов с ссылочками на листочки поплыл) Полезно однако)
Рад что помогло =))
Могу про лямбду добавить: есть вот люди, которые постоянно везде суют лямбду, т.е.
x = lambda y: y ** 2
print(x(5))
Сделайте вид, что тут что-то сложное. И вот, часто замечал, что многие любят делать огромные строки, где тупа одна лямбда как какая-то функция
Это нарушение PEP8 про длину строки и ещё одно нарушение, что лямбда используется неправильно (даже в пепе есть (!!))
Правильно лямбда используется в таких моментах: print(sorted(["c", "b", "a"], key=lambda x: x[0].lower())) # prints: ['a', 'b', 'c']
Это просто пример, но думаю суть ясна.
Вооооооооооооооооот, да
Можешь напомнить плз, какой дистрибут линукса ты юзаешь???
ZorinOS
Привет, а каким дистрибутивом ты пользуешься?
Вроде как это манжаро какая-то
ZorinOS
@@zproger Спасибо
Это же чистый код в вольном пересказе, хосподе, это же такая база
ещё бы =)
Правильные советы, только возвращаемый тип в первом примере лучше сделать list[int].
def - создаёт объект класса function, которому назначаются поля. Если мы не переопределяем эти поля при вызове функции, естественно мы работаем со значениями, которые уже определены для полей. За счёт этого, как я понимаю, работают всякие функции-генераторы. Да, это поведение не вполне очевидно, если мыслить в рамках процедурного программирования, к сожалению.
На питоне пишу неделю.
До этого практически ничего не кодил . Какой прием успел вывести:
Сперва высматриваю в задаче задачки поменьше. То есть, пишу мини библиотеку методов под одну задачу. Нафига: а чтоб не запутаться.
Это как собирать дом готовыми модулями. Конечно не все действия так заранее прописываю, только более или менее типовые.
Привет! Спасибо за ролик! Очень не хватает разбиение ролика на таймкоды :(
Я тут в общем, пишу функцию и тут ты! Спасибо, обязательно посмотрю позже!
Я проверяю инстансами, и зачастую люблю писать в одну строку так: ('True' if mesg == 'hi' else 'False'), [i for i in mesg....]
Не пиши буль не булем
True/False должны быть без "", а ещё у тебя здесь проблемы c алгебра-логикой и можно сделать просто return mesg == "hi"
@@MagMigo
1.С булами затупил немного когда писал это, а так, я делаю реальными булами без " "
2.Нет, у меня нет проблем с логикой, я не сказал ещё если в друг мне нужно по листу пройтись или написть что-то если Тру или Фолз
Примерно так, выглядит моя функция:
def hello(text):
if not isinstance(text, list):
raise ...
return [i for i in text if i == 'Hey']
@@scrooge6603 Уже в этом случае нет проблем, но если ты будешь делать так
def hello(text: str) -> bool: # Допустим, тебе будет нужна функция, где тебе надо чтоб возвращался только буль
return isinstance(str, text)
Под алгебра-логикой я это имел ввиду.
3:12 Вы хоть сами поняли, что написали, может быть вы имели from lib import * : в таком случае все функции и классы запишутся в основной модуль
А если import lib : то к функциям и классам придётся обращаться через имя библитеки и уникальность уже не обязательна
действительно, даже и не заметил как написал это
Ну ошибся человек, с кем не бывает
Видео очень хорошее, но можно было бы сюда сразу теории докинуть, так как в видео упоминается, и про Single responsibility principle , и про DRY, и про KISS
bad practice делать импорт через *
Согласен
7:04 а что тут не так? вполне может быть оберткой для трубы, а далее уже по логике
но название и действия должны как-то матчится
2:06 это же язык динамической типизации зачем резать на входе-то? Массивы же разные могут быть, тут или имя менять или логику внутри функции.
Всё правильно. Если даже тебе нет дела до тех, кто согнал тебя с работы, и теперь поддерживает твой код, позаботься о себе драгоценном. Понять собственный код, который ты писал год назад, особенно в крупном проекте, на пару сотен питон-файлов, очень не просто. Надо осмысленно называть модули, функции, классы, и даже соорудить простейший сервер с документацией и поиском по ней.
Из последнего коротко: меньше кода, больше функционала.
Args мне кажется довольно полезной штукой. По крайней мере в js используется не так уж редко.
Вместо, а даже лучше вместе с комментариями хорошо использовать докстринги. Если не хочется лезть в модуль и вычитывать там функционал функции, просто пишешь хельп(), и он у тебя на ладони. Тоесть в докстринги пишем комментарии по использованию, в обычные коменты - по реализации
Да, вот только кликнуть по функции быстрее, чем вызывать help, но docstring крутая штука
Я человек простой, тыкаю пальцем в букварь - называю функцию
😮
Хороший видосик)
=)
Скажите, пожалуйста. Почему функция называется get_array, если возвращает не array, а list?
Список в питон практически тоже самое, что и массив
Да, всё же разное, но имеет место быть
@@MagMigo Это не практически тоже самое, у массивов есть свой тип, и все его элементы одного типа. А в списках типа нет, и элементы могут быть любые.
Ну это ведь пример) а вообще списки и массивы отличаются между собой, и об этом есть след.видео:
ruclips.net/video/_V4G4A9vehI/видео.html
1. Документируем только функции или методы класса
2. Пишем чистый код
Вот и всё))
Что за приложение для кода?
*args и **kwargs исползуетса доволна часто в декораторах и прий написаний библиотекий
Что-то все в кучу и солид принципы и нейминг и аннотация и изменяемые типы.
Это да, но думаю лишним не будет
Аннотации мне тоже показались неожиданными в этом видео, а остальное - всё по теме.
А чё делать на C++? Там нет всех этих удобных штучек, все сердито
Писать с нуля =)
возможно имеет смысл рассказать как избегать цыкличных импортов?
Да, расскажу в ближайшем видео
Крутое и полезное видео, но про память все равно не понял
Хорошая практика имхо - не писать комменты на каждой строке функции, а документировать ее той же док строкой…
какой у вас дистрибутив?
ZorinOS
Я наверно спрошу какую-то глупость...
Я понял, что функция append_score где-то там внутри хранит значение аргумента по умолчанию - список по умолчанию scores - и при каждом вызове функции без указания аргумента по умолчанию этот "список по умолчанию" дополняется.
Вопрос - как добраться до этого "списка по умолчанию" извне этой функции? Или инкапсуляция этого не позволит?
То есть - вызвали функцию без аругмента по умолчанию, она внутри себя создала переменную типа указатель (с простым числом это не прокатывает), этот указатель указывает на одну и ту же область памяти, и при каждом вызове функции без аргумента по умолчанию содержимое этой области памяти ("список по умолчанию") последовательно модифицируется. И этот "список по умолчанию" хранится до конца работы пограммы, но до него никак не добрешься?
Я примерно предполагаю ответ - доступ к этому "списку по умолчанию" должен быть предусмотрен логикой программы, в данном примере такого доступа нет - ну и доступа нет.
Но все равно страннно.
В этом есть какой-то полезный смысл, или это побочный эффект архитектуры Питона?
Есть конечно доступ через магические методы, спроси чат жпт
import lib import *
хм...
Может всё таки from lib import *?
да, там ошибка которую я неосознанно совершил
Ну, первый совет - это очень круто, но чревато циклическим импортом. Я ставлю описание типа в doc string.
Чтоб решалась проблема с цикличным импортом и существует константа typing.TYPE_CHECKING
Раз 10 за 3-4 года использовать *args и **kwargs - смешно
Самый банальный и частоиспользуемый пример - wrapper'ы
мдеее. Товарищи, пишите на шарпе. лучше шарпа ничего нет и никогда не будет!
у каждого свой идеальный язык =)
дядя Боб для маленьких
:)
4 года сижу на питоне, аргсы и кваргсы использовал только в обучении. Что я делаю не так?
В формах в джанго не попадались? Например добавить данные из базы в форму?
не наследуешь методы у сложных классов с полиморфизмом)
про датаклассы расскажи. Слотс, фриз там вот это вот всё
почему-то мне вспомнился YANDERE simulator
Странно :D
Вау, 30к, супер!
=)
А что делает **? Одинарная * это распаковка, а двойная для чего?
* - распаковка списков
** - распаковка словарей
Пусть тебе из множества N возможных лайков, return N[-1]
Зачет)
А где в видео разбор проблемы с картинки?
Почти все про очевидные вещи, да и не все они фатальны
Насчет args, kwargs не совсем согласен, часто использую, особенно когда нужно наследовать какой-либо класс и добавить в него свой функционал, не изменяя уже существующий, но пример из видео, да, согласен - ужас)
Имелось в виду не использовать тогда, когда без него можно спокойно обойтись =)
@@zproger ну это да, просто вы начали говорить, что за все время раз 5 использовали, мне это показалось странным
А будет контент по rust?
Хотелось бы, но опыта в нем ещё маловато
@@zproger Как и у меня. Каждый день узнаю что-то новое для себя.
Нафига, а главное зачем? Этот язык уже давно дед инсайт
@@robertobokarev439 че несёшь, раст развивающийся и хороший язык
Найс, выучил Python, теперь иди учи английский, потому что циклы циклами, а названия за тебя никто не придумает :D Спасибо за полезный материал! Но не проще ли просто писать коммент к функции и не париться с придумываем названий, особенно когда у тебя в одной проге 100500 этих функций и уже фантазия закончилась :D
В плане типов данных, принимаемых аргументов проблема всех не строго типизированных языков. На Цпп такого не встретить
Здравствуйте, одна маленькая поправочка: Вы здесь имеете в виду языки со _статической типизацией_, где типы переменных и выражений объявляются программистом или выводятся компилятором. Определение же "строгой/слабой" типизации зависит от сообщества, в котором употребляется. Иногда термин "строгая типизация" используется как синоним статической типизации (как в Вашем комментарии), но есть также и такое (на мой взгляд, лучшее) определение: язык является "строго типизированным", если он не позволяет нарушить собственные абстракции (такие, как типы данных) (по крайней мере, в "безопасных" контекстах). В таком понимании язык Python является строго типизированным языком с динамической типизацией, а C++ является слабо типизированным языком со статической типизацией (т.е., понятия "строгости" и "времени" типизации ортогональны). Просто мои пять копеек, думаю, кому-то будет полезно знать о таких альтернативных определениях ;-)
Странно, ролику больше года и ни одногт лайка?
спс за видосян
Рад стараться =)
При чём тут пайтон? Данные рекомендации относятся к большинству языков программирования
Согласен, но примеры именно на Python, поэтому назвал видео таким образом.
@@zproger Да, это понятно. Просто точно такие же темы обсуждаются в других языках программирования и точно так же не указывается что это общие правила программирования.
Но понравилось чьё-то высказывание: "Самое главное и самое сложное в программировании- правильно назвать функцию".
Пожалуйста не юзайте списочные выражение с лямбдой на лямбде заправленной условиями и распаковкой. Это буквально криг души и каждый раз хочется орать когда видишь такой код
Пожалуйста, ТАЙМ-КОДЫ!
Тут бы зашел тикто надо вот так
Во второй ошибке (про уникальность имён функций и конфликт с другими либами) откровенно говоря бред. По вашей логике, человек при подключении библиотек должен прочитать абсолютно все ее функции и их имена, чтобы не повториться, вместо того чтобы просто нормально импортировать.
Да и вообще можно было приличия ради добавить, как решить проблему ссылочного типа в аргументе
IDE подскажет если ты перезапишешь функцию из модуля это раз.
Как правило в модулях просто функций нет, есть только методы внутри класса это два. Скорее речь шла о ваших собственных модулях.
Не используйте wildcard import это три)
Разбей видос на главы, а то некоторые фичи я уже знаю, а где ты описываешь другие я хз
Спасибо, огромное за такие ролики, жалко, что ты не можешь сравниться с активностью с миллиониками которые снимают говно контент
Ну я выпускаю видео каждые 7 дней, за ~3 года ни разу не отошел от этих сроков =)
@@zproger смотрю тебя как аниме сериал еженедельно ждя новые серии :D
:D
@@zproger имелось ввиду активностью на канале: просмотры, лайки и т.п.
А, ну если снимать гавно то тоже будет активность большая) Но мне не интересно такое снимать
Можете порекомендовать ресурс для изучения Python, может книжку какую-то? Оплачивать обучение на данный момент не очень хочу, как минимум потому что мне 15 лет. Смотрел уже 3 бесплатных курса на ютубе, но хочу продвигаться дальше.
Sololearn, Проект Эйлера (первые 35 упражнений, дальше больше математика. С какого-то момента сложность резко возрастает, так-что несколько дней на упражнение станет нормой) и если совсем ноль в программировании "Грокаем алгоритмы". Когда добрался до них показались примитивными, но может просто забыл как учился ездить на велосипеде.
Дальше гугл, свой проект и возможно Лутц. Лутц это не учебник, а скорее справочник. Читать только чтобы убедиться что ничего не пропустил, и то через год-полтора.
Советую так же уже сейчас учить слепую печать. Полотенце на клавиатуру, указательные на пупырки и 30 минут в день месяц-полтора. После такой базы скорость печати вернется на прежний уровень и практику можно будет набивать на бытовом печатании. Сам проходил в 14, когда даже не думал о программировании. Зачем? В темноте не было видно клавиатуры :D
Ах да, нулевой язык программирования - английский. Любой интернетный текст в зубы (Литературный носители переусложняют) и переводим гугл-переводчиком слово за словом примечая частые. Первые 50 часов ничего в голове задерживаться не будет, и это нормально. И не стоит гнаться за "100%" английским. Его не бывает. Игровой, ютуберный, программисткий, математический английские - выбери кусочки и все. По своему опыту так же скажу, что чтение можно выучить в вакууме. Произношение, слух и разговор можно отложить лет до 20. Так же для мотивации идеально подойдут уроки. В 9 классе за вами как раз перестанут следить, если не уже.
Ну и бонус за простыню. Написано так ясно, что переводчик переводит как с русского на русский: betterexplained.com/articles/a-visual-intuitive-guide-to-imaginary-numbers/
корисно
Спасибо!
ПОЧЕМУУУУ ФУНЦИЯ?????
Что
Потому, что не процедура
Ничего полезного. Очередной говнокод от виндузяшника
ну не смотрите тогда, никто не заставляет
Грамотно
Благодарю
А ещё, когда опорожняетесь- снимайте штанишки. Для кого этот мануал? Я без негатива к автору, просто интересно- есть люди, которые изучают синтаксис/продвинутый уровень и для них это не очевидно?
угу, знаю таки, кодят как орки, знают кучу языков и фреймворков
и не один не используют нормально