RXL
Технический
Администратор
Offline
Пол:
|
|
« : 31-10-2010 09:37 » |
|
Собираюсь в этой теме писать свои впечатления о Python. Ну, и если что-то будет не понятно, то и вопросы.
Читаю книгу "Программирование на Python 3. Подробное руководство." Марка Саммерфилда.
Т.к. я только начал читать, то конечно картина у меня очень ущербная и тем не менее возникают вопросы "на будущее".
1. Встроенные типы. К ним относится только int и str, или bool, float и complex тоже?
2. Прочел о неизменности встроенных объектов. Пояснение к вопросу:
obj.x = 1 a = obj.x obj.x = 2 # a = 1, obj.x = 2
Хочу, чтобы и a изменялось. Т.е. иметь ссылку в понимании других языков (C++, Perl, PHP). Иначе это просто принцип copy-on-write - создание нового объекта при изменении. По сути - присваивание по значению. Хочу полноценную ссылку. Такое тут есть?
3. Комбинирование логических операторов.
1 <= a <= 3 # понятный аналог из SQL: a between 1 and 3
Это конечно здорово, в плане компактности, но как-то сильна сишная привычка, что операторы должны быть легко различимы, чтобы не путаться в сложных выражениях.
4. Оператор is. Я так понял, это похоже на === в Java и PHP. Правильно?
5. Оператор in. Очень приятная неожиданность, что он не только с коллекциями работает, но и со строками. Хорошо ли это на самом деле - покажет практика.
6. Как я понял, в Питоне нет автоматического приведения числовых и строковых типов, как во многих скриптовых языках. Это так?
|
|
« Последнее редактирование: 31-10-2010 09:45 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #1 : 31-10-2010 15:07 » |
|
1.все типы, которые ты можешь найти в __builtins__ (там еще много других) 2. когда ты говоришь a = obj.x в си: void *a, *x; a = x; x= y; // a не изменилось
здесь так же 3. отсутствует напрочь, как и в C/C++, Java, c# придется записывать полностью: a <= 1 and a <=3 4. сравнение по ссылке. есть некоторое множество объектов (Классы - это тоже объекты), которые являются синглтонами. для == вызывается __eq__ класса, если есть, в противном случае сравниваются всегда уникальные id (это может быть,например, адрес в памяти) 5. работает в любых классах, где есть функция __contains__ 6. есть только с числами. (1.3 + 33) даст верные 34.3. а вот ("a"+1) даст ошибку, нужно написать "a" + str(1). тип str(a) вызовет a.__str__(), repr(a) вызовет a.__repr__()
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #2 : 31-10-2010 21:52 » |
|
2. Твой пример неверен. Посмотри мой еще раз. Главное - изменение и доступность нового значения через ранее полученные ссылки. 4. Не о том, но расцениваю как "да" 5. Пока мне до этого читать и читать. Книга мне уже не нравится. т.к. столько воды, что начинаю читать по диагонали и могу пропустить что-то полезное. 6. Понятно. В общем-то, это верное решение. Новые вопросы: 7. Можно ли разбивать выражение на несколько строк? a = b + c + d + e 8. Есть ли какие-либо ограничители для команд? Мне их не хватает. Создается ощущение, что работаешь с VB. 9. Константы True, False и None чувствительны к регистру написания? Неудобно писать их в большой буквы. Опять ощущение VB. Добавлено через 12 минут и 14 секунд:10. Книга пока не осветила вопросы отступов. Будут ли идентичны следующие отступы? # "." - пробел, "t------" - табуляция. ............# 12 пробелов t---t---t---# 3 табуляции (из расчета по 4 позиции) t-------....# 1 табуляция (из расчета по 8 позиций) и 4 пробела ...t----....# 3 + табуляция + 4
Вопрос важный, т.к. разные редакторы работают по разному.
|
|
« Последнее редактирование: 31-10-2010 22:04 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
npak
|
|
« Ответ #3 : 31-10-2010 22:05 » |
|
Рома, по поводу ссылок на встроенные типы - а где это иначе? В Java, Javascript, PHP - при присваивании переменной или поля объекта, содержащего примитивный тип, значение копируется.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #4 : 31-10-2010 22:08 » |
|
Коль, вот тебе пример из PHP. <?php
$a = 1; $b = &$a; $a = 2;
echo "$a, $b\n" # 2, 2
?>
именно это я имел ввиду - создание ссылок на изменяемое значение. Тоже самое в Perl. Насчет JS - там нет таких ссылок.
|
|
« Последнее редактирование: 31-10-2010 22:10 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 01-11-2010 05:28 » |
|
RXL, как-то не очень понятна суть проблемы. Понятно, что в том же Perl есть синтаксические правила обращения к сложному объекту по ссылке, но в то же время непонятен смысл ссылки на значение простого типа - его копирование не дороже копирования ссылки. И различается это как-то даже интуитивно: // Копирование значений var a = 1; var b = a; a = 2; WScript.Echo(String(a) + ", " + String(b));
// Работа со ссылками var a = {x: 1}; var b = a; b.x = 2; WScript.Echo(String(a.x) + ", " + String(b.x)); >cscript test.js Сервер сценариев Windows (Microsoft R) версия 5.8 c Корпорация Майкрософт (Microsoft Corp.), 1996-2001. Все права защищены.
2, 1 2, 2
Если, допустим, нужно передать в функцию параметр, изменяемый функцией - достаточно упаковать его в объект.
|
|
« Последнее редактирование: 01-11-2010 05:30 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #6 : 01-11-2010 07:49 » |
|
Дим, я просто пытаюсь выяснить, есть ли подобная возможность в Питоне. В Перле можно ссылаться на что угодно - даже на скаляр. В и PHP можно, и в C++ можно. Практическая сторона, к примеру - передача скаляра по ссылке в функцию.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sla
|
|
« Ответ #7 : 01-11-2010 08:46 » |
|
8. Есть ли какие-либо ограничители для команд? Мне их не хватает. Создается ощущение, что работаешь с VB. hello = "This is a rather long string containing\n\ several lines of text just as you would do in C.\n\ Note that whitespace at the beginning of the line is\ significant."
print hello Добавлено через 31 минуту и 48 секунд:а вот прикольный примерчик hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C."
print hello Обрати внимание на rДобавлено через 5 минут и 35 секунд:интересен доступ к строке word = 'Help' word[3] 'p' word[0:2] 'He' word[2:4] 'lp' '<' + word*5 + '>' <HelpHelpHelpHelpHelp>' Добавлено через 23 минуты и 55 секунд:в этом месте меня клинит word[0] = 'x' Ошибка... Т.е. получается что word[0] - это функция, а не элемент строки. Добавлено через 18 минут и 43 секунды:не люблю такие конструкции a, b = 0, 1 # здесь еще можно согласиться while b < 10: print b a, b = b, a+b # здесь - никогда.
Кстати, можно несколько операторов на одной строке? где показанном коде конец ограничитель цикла? Пустая строка?
|
|
« Последнее редактирование: 01-11-2010 09:18 от Sla »
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #8 : 01-11-2010 09:41 » |
|
в этом месте меня клинит
word[0] = 'x'
Ошибка... Т.е. получается что word[0] - это функция, а не элемент строки.
Просто строка неизменная. Можно склеить из частей: word = 'x' + word[1:] Добавлено через 3 минуты и 25 секунд:не люблю такие конструкции a, b = 0, 1 # здесь еще можно согласиться while b < 10: print b a, b = b, a+b # здесь - никогда.
Кстати, можно несколько операторов на одной строке? где показанном коде конец ограничитель цикла? Пустая строка? Такие конструкции - суть есть списки. Но обычно, в других языках, списки ограничивают скобками. Т.ч. согласен, что это безобразие. Ограничителем блока (цикла) будет другой отступ. Такая вот хрень. По этому меня очень интересует вопрос 10. Добавлено через 1 минуту и 46 секунд:hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C."
print hello Обрати внимание на rВ чем фишка?
|
|
« Последнее редактирование: 01-11-2010 09:46 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Вад
|
|
« Ответ #9 : 01-11-2010 11:01 » |
|
интересен доступ к строке
word = 'Help' word[3] 'p' word[0:2] 'He' word[2:4] 'lp'
>>> word[-4:-1] 'Hel'
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #10 : 01-11-2010 11:14 » |
|
да с отрицательными "индексами" интересно - почитал но я в ступоре if c < self.base: c = self.base if d < self.base: d = self.base if n < self.base: n = self.base if c > self.top: c = self.top if d > self.top: d = self.top if n > self.top: n = self.top self.c = c Где здесь концы блоков if?
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Вад
|
|
« Ответ #11 : 01-11-2010 11:37 » |
|
Где здесь концы блоков if?
Должны быть согласно отступа. Отступ одинаковый - if-ы на одной глубине, отступ больше - if вложенный.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #12 : 01-11-2010 11:37 » |
|
Дим, я просто пытаюсь выяснить, есть ли подобная возможность в Питоне. Так вот мне и стала любопытна причина такого интереса. Я бы именно этой возможностью заинтересовался в последнюю очередь, а может быть никогда бы не заинтересовался. Практическая сторона, к примеру - передача скаляра по ссылке в функцию. Очень редко сталкиваюсь. Рефлексия на тему тех или иных возможностей языка помогает понять собственные подходы к программированию и отвязывать эти подходы от конкретного языка. Где здесь концы блоков if? Полагаю, нужно считать отступы
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Sla
|
|
« Ответ #13 : 01-11-2010 11:45 » |
|
считать отступы... Взрыв мозга \tif : \t\t... _______________... Где конец блока? ________if : __________... _________... Где конец блока? зы читаю вот это
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
npak
|
|
« Ответ #14 : 01-11-2010 11:49 » |
|
a, b = 0, 1 # здесь еще можно согласиться while b < 10: print b a, b = b, a+b # здесь - никогда.
Кстати, можно несколько операторов на одной строке? где показанном коде конец ограничитель цикла? Пустая строка? Цикл кончится в следующей строке, отступ которой будет равен отступу инструкции while, при этом пустые строки игнорируются. Другими словами, тело цикла состоит из строк, чей отступ больше, чем отступ while, и пустых строк.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #15 : 01-11-2010 11:52 » |
|
Ткните ссылкой на синтаксис языка.
про отступы понятно интуитивно
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
npak
|
|
« Ответ #16 : 01-11-2010 12:08 » |
|
Sla, не уверено, что "интуитивно", зато исчерпывающе: http://docs.python.org/reference/lexical_analysis.htmlЕсли своими словами, то инструкция (statement) должна укладываться в пределах одной логической строки. Логическая строка состоит из одной или нескольких физических строк. Для склеивания нескольких физических строк в одну логическую последним символом в склеиваемых строках должен иди бэкслэш: if 1900 < year < 2100 and 1 <= month <= 12 \ and 1 <= day <= 31 and 0 <= hour < 24 \ and 0 <= minute < 60 and 0 <= second < 60: # Looks like a valid date return 1 Табуляция разворачивается в пробелы таким образом, чтобы длина отступа была кратна 8. То есть \t\t - развернутся в 16 пробелов ___\t (три пробела и табуляция) - развернутся в восемь пробелов Пустые строки игнорируются
|
|
« Последнее редактирование: 01-11-2010 12:16 от npak »
|
Записан
|
|
|
|
npak
|
|
« Ответ #17 : 01-11-2010 12:19 » |
|
Где конец блока?
________if : __________... _________...
Где конец блока?
В примере с if отступы сформатированы неправильно. отступ последней строки не соответствует ни отступу if, ни отступу предыдущей строки. Поэтому интерпретатор питона на такой текст сругается: IndentationError: unindent does not match any outer indentation level
|
|
|
Записан
|
|
|
|
npak
|
|
« Ответ #18 : 01-11-2010 12:37 » |
|
Так, с индентацией вроде разобрались Теперь про ссылки. Ссылок (в смысле PHP и С++) в питоне нет. в этом он ближе к Java. Как написал Арсений, выражения a.x = 0 лучше рассматривать как аналог Сишных поинтеров: Пример RXL переписывается на "Си" так: / *obj.x = 1 a = obj.x obj.x = 2 */ some_class * obj = /* какой-то объект */; /* тип obj->x - УКАЗАТЕЛЬ на значение, а не само значение! */ object * a; /* тип переменной - УКАЗАТЕЛЬ на значение, а не само значение */ *(obj->x) = 1; *a = *(obj->x); *(obj->x) = 2 Вполне логично, что после повторного присваивания obj.x его значение будет отличаться от сохраненного в переменной а. Разумеется, эта Си-подобная метафора не показывает всей правды - для встроенных типов может быть предусмотрена более эффективная схема хранения, но в общем случае она работает. Поэтому для того, чтобы передать в функцию ссылку на число, нужно передавать туда объект, в котором число будет полем. Например class NumRef: ref = 0 def __init__(self, x): self.ref = x;
Тогда можно реализовать Си++-шную идиому, когда основное значение возвращается из функции, а дополнительные - через ссылки: // C++ char * read(int& count) { /* число прочитанных символов передается через size */ } #Python def read(sizeRef): # что-то делаем sizeRef.ref = size return buf
Но в питоне специально для этого придумали возвращать тьюплы (tuple) - можно вернуть несколько значений пачкой: def read(): # что-то делаем return buf, size
res,size = read()
Следовательно, нет необходимости передавать что-то по ссылке. Необходимое значение можно передать либо как поле объекта-параметра, либо в тьюпле
|
|
« Последнее редактирование: 01-11-2010 12:39 от npak »
|
Записан
|
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #19 : 01-11-2010 12:57 » |
|
неизменность внутренних объектов - есть неизменность внутреннего содержания объектов. мой пример верен. то есть если >>> a = 'hello' >>> a.replace('l','b') 'hebbo' >>> a 'hello'
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #20 : 01-11-2010 13:11 » |
|
Вот - потенциальная проблема при работе с виндовыми редакторами, интерпретирующими табуляцию не по кратной 8 позиции.
Добавлено через 10 минут и 46 секунд: npak, Арсений(TjSoft), в общем, понятно.
|
|
« Последнее редактирование: 01-11-2010 13:22 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #21 : 01-11-2010 15:49 » |
|
я использую настроенный vim "чисто питоновских" редакторов очень много. См. страничку на python.org
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #22 : 01-11-2010 15:57 » |
|
я так понял, что инструкций switch и case не существует есть if : elif :
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #23 : 01-11-2010 16:19 » |
|
Арсений, наверно я все же не буду изменять своим привычкам ради одного языка: cedit в Linux и nodepad++ в винде. Оба редактора вполне адекватны. Опасность неправильных табуляций больше в совместной работе, чем в одиночной. Добавлено через 1 минуту и 3 секунды:Слава, да, таких ключевых слов нет. Собственно, я так понимаю, все на if делается. Добавлено через 1 минуту и 30 секунд:Switch statements in Python
Python doesn’t support a native switch statement. I’ve found myself using the following coding idiom instead recently which seems to work pretty well:
{'option1': function1, 'option2': function2, 'option3': function3, 'option4': function4}[value]()
This works with lambdas as well, for inline calculations. Here’s a switch statement that assigns to a variable in PHP:
switch ($value) { case 'a': $result = $x * 5; break; case 'b': $result = $x + 7; break; case 'c': $result = $x - 2; break; }
And here’s the equivalent code in Python:
result = { 'a': lambda x: x * 5, 'b': lambda x: x + 7, 'c': lambda x: x - 2 }[value](x)
Через массив лямбда-функций. Прочие значения отлавливать через exeception? Добавлено через 9 минут и 47 секунд:Кстати, не трудно догадаться, почему в Питоне нет switch-case: все дело в тех же отступах - сложно будет определить блок. Вот обсуждение 2006-2008 годов: http://www.python.org/dev/peps/pep-3103/
|
|
« Последнее редактирование: 01-11-2010 16:34 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #24 : 01-11-2010 17:25 » |
|
я так понял, что инструкций switch и case не существует
Видимо - пока. хотя особых преимуществ этой конструкции не вижу. if-elif-else - более гибкая Добавлено через 1 минуту и 7 секунд:RXL, и не только через лямбду!
|
|
« Последнее редактирование: 01-11-2010 17:26 от TJSoft »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #25 : 01-11-2010 18:47 » |
|
хотя особых преимуществ этой конструкции не вижу. if-elif-else - более гибкая Этот вопрос уже обсуждался на форуме. Switch для простых типов может быть преобразован транслятором языка в хэш-таблицу, алгоритмическая сложность выбора элемента из которой равна 1. Цепочка if-elif всегда вычисляется как последовательность условий и переходов, поэтому её алгоримическая сложность равна n. Это преимущество, которое ты не видишь: таблица функций (опуская затраты на конструирование таблицы) работает быстрее. Особенно актуально в случае программирования сложных автоматов с длинными switch'ами атомарных/скалярных значений.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #26 : 01-11-2010 19:03 » |
|
Пробуя примеры с исключениями наткнулся на ошибку интерпретатора. File "./t1.py", line 7 except EnvironmentError as e: ^ SyntaxError: invalid syntax
Версия имеющего Python - 2.4.3. Смысла ошибки не понимаю, т.к. в доке на их сайте на нашел упоминания, чтобы конструкция as была введена в какой-то определенной версии языка.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #27 : 01-11-2010 19:45 » |
|
ты небось доку по 2.7 читаешь? Добавлено через 1 минуту и 41 секунду:открываем для 2.4.3 и видим, что никакого as нету http://docs.python.org/release/2.4.3/ref/try.html#try
|
|
« Последнее редактирование: 01-11-2010 19:47 от TJSoft »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #28 : 01-11-2010 19:51 » |
|
Читал это: http://docs.python.org/reference/compound_stmts.html#exceptВерсия там не указана.Да-да, на самом верху, в углу написано - 2.7... Добавлено через 11 минут и 2 секунды:Честно говоря, такие скачки синтаксиса у языка 20 лет отроду пугают.
|
|
« Последнее редактирование: 01-11-2010 20:04 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #29 : 01-11-2010 20:56 » |
|
Последние годы он очень сильно развивается. Особенно благодаря
|
|
|
Записан
|
|
|
|
|