You are viewing avysk

301 Moved Permanently - Удивительное рядом
May 4th, 2010
10:47 pm
[User Picture]

[Link]

Previous Entry Share Next Entry
Удивительное рядом

$ python
Python 2.6.5 (r265:79063, Mar 31 2010, 18:32:31)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(x, y={}):
... y[x]=1
... print y
...
>>> f(1)
{1: 1}
>>> f(2)
{1: 1, 2: 1}
>>>


Они называют это деталями реализации.

Апдейт для непонятливых:

1. Мне не нужно объяснять, *почему* оно так работает. Я понимаю.

2. Я ничего против питона не имею. Очень приятный язык, лучше многих.

3. Но данное конкретное место вызывает у меня резкое отвращение.

Tags:

(29 comments | Leave a comment)

Comments
 
[User Picture]
From:nidd
Date:May 4th, 2010 08:04 pm (UTC)
(Link)
я это понял когда хотел сделать что-то типа

def f(x, y = ff()):
....
From:nikolaypultsin
Date:May 4th, 2010 08:11 pm (UTC)
(Link)
Может, это случайность, но я вот в курсе. (На питоне не писал, но слышал студенческий доклад.)

Вообще-то, достаточно разумная оптимизация -- зачем передавать объект в качестве дефолтного значения параметра (то есть не возвращать его наружу) и при этом менять его внутри функции?
[User Picture]
From:avysk
Date:May 4th, 2010 08:19 pm (UTC)
(Link)
Теоретическую базу я и сам под что хошь подведу. :-)
[User Picture]
From:avysk
Date:May 4th, 2010 08:21 pm (UTC)
(Link)
Думаю, что случайность, так как мсс не знал.
[User Picture]
From:lvader
Date:May 4th, 2010 08:22 pm (UTC)
(Link)
ну вообще это предсказуемая вещь. где-то встречал и в описаниях и в тестах.
[User Picture]
From:avysk
Date:May 4th, 2010 08:26 pm (UTC)
(Link)
Саша, я верю, что это не просто уродство, а документированное уродство.
[User Picture]
From:lvader
Date:May 4th, 2010 08:49 pm (UTC)
(Link)
вообще-то не уродство а вполне предсказуемая вещь. {} - это же не константа.
[User Picture]
From:avysk
Date:May 4th, 2010 09:00 pm (UTC)
(Link)
Нет, {} -- как раз константа. Покажи-ка мне любой другой код, в котором {} не будет означать пустой словарь.

Вот если a = {}, то a -- не константа, да. Но это не объясняет синтаксиса, в котором {} может означать невесть что.
[User Picture]
From:avysk
Date:May 4th, 2010 09:16 pm (UTC)
(Link)
Иллюстрация:

>>> {}[1]=2; print {}
{}

>>> a={}; a[1]=2; print a
{1: 2}
From:nikolaypultsin
Date:May 4th, 2010 09:22 pm (UTC)
(Link)
Ты лукавишь. Возможность записи
{}[1] = 2
означает, что {} -- не константа.
[User Picture]
From:avysk
Date:May 4th, 2010 09:32 pm (UTC)
(Link)
Ничего это не означает. Значение {} изменилось? Нет? Значит -- константа. Да, где-то из {} был создан какой-то новый словарь, но это больше не {}.

А в примере с a словарь как был a, так и остался.

Ты ещё скажи, что 0 -- не константа, так как к нему можно прибавить единицу. Просто языки типа C не позволяют идиотской записи 0++ или что-нибудь в этом роде, а питон позволяет идиотскую запись с пустым словарём, поскольку детали реализации такие.
From:nikolaypultsin
Date:May 4th, 2010 09:21 pm (UTC)
(Link)
Вот пример, не шибко осмысленный, но ты не просил, чтобы был смысл:
{}.setdefault("key", "value")
[User Picture]
From:avnik
Date:May 4th, 2010 09:23 pm (UTC)
(Link)
{} это синтаксический сахар для dict()

def foo(x, y=dict()):
pass

все что до первого отступа -- часть конструкции def и выполняется "одновременно с ней" и одноразово. В замыкание попадает созданый экзепляр.
[User Picture]
From:avysk
Date:May 4th, 2010 09:27 pm (UTC)
(Link)
Да я понимаю, *почему* оно так происходит. Дело-то не в этом.
From:nikolaypultsin
Date:May 5th, 2010 09:31 pm (UTC)
(Link)
Спасибо, хороший пример для объяснения, что такое "синтаксический сахар". Я более сложные часто привожу зачем-то.
[User Picture]
From:lvader
Date:May 5th, 2010 07:24 am (UTC)
(Link)
Скажи, а вот такой результат тебя удивляет ?
$ ./4
0x100000f00
0x100000f00

для вот такого кода:
$ cat 4.c
#include
[Error: Irreparable invalid markup ('<stdio.h>') in entry. Owner must fix manually. Raw contents below.]

Скажи, а вот такой результат тебя удивляет ?
$ ./4
0x100000f00
0x100000f00

для вот такого кода:
$ cat 4.c
#include <stdio.h>

int main(){
f();
f();
}

void f(int a){
char *s = "Test";
printf("%p\n", s);
}

[User Picture]
From:avysk
Date:May 5th, 2010 09:08 am (UTC)
(Link)
С какой стати должен удивлять? У тебя "Test" - константа. Думаю, что если попробовать ее изменить, словишь сегфолт.
[User Picture]
From:lvader
Date:May 5th, 2010 10:12 am (UTC)
(Link)
я за то что это один объект. в питоне {} - это не константа, а instance объекта dict. но все так же один объект, просто что segfault не геренится когда ты его меняешь.
[User Picture]
From:lvader
Date:May 5th, 2010 07:26 am (UTC)
(Link)
объясняет, ибо {} раскрывается всего один раз при объявлении функции, а не каждый раз при ее вызове.
[User Picture]
From:avysk
Date:May 5th, 2010 09:10 am (UTC)
(Link)
Еще раз - я понимаю, почему оно так работает. Под "не объясняет" имеется в виду "не объясняет идиотский синтаксис".
[User Picture]
From:lvader
Date:May 5th, 2010 10:14 am (UTC)
(Link)
обычный синтаксис. просто надо понимать что {} это не константа.
[User Picture]
From:slobin
Date:May 4th, 2010 10:20 pm (UTC)
(Link)
Кстати, раз уж ты на эти грабли наступил, лови полезное следствие: в конструктор collections.defaultdict передаётся не значение по умолчанию, а фабрика значений по умолчанию. То есть, например, не defaultdict({}), а defaultdict(dict()). Причина теперь должна быть понятна. К счастью, все имена встроенных типов являются фабриками полезных "пустых" значений. int() возвращает ноль, поэтому идиоматично писать defauldict(int). Но, если очень хочется, можно и defauldict(lambda:0), работать будет так же, только медленнее. ;-)

... Государственный разъяснитель третьего ранга ...

[User Picture]
From:slobin
Date:May 4th, 2010 10:24 pm (UTC)
(Link)
Опечатка: должно быть defaultdict(dict). Пустая пара скобок после dict была лишняя.

... Ice tu ei, hoi Brutus? ...

From:nikolaypultsin
Date:May 5th, 2010 07:10 pm (UTC)
(Link)
Кстати, не ты ли мне показывал собственный код на C, в котором была static переменная внутри функции? И не понимал, почему мне это не нравится? В чем тут существенная разница, кроме того, что ты знаешь C и значение слова static в нем?
[User Picture]
From:avysk
Date:May 5th, 2010 07:12 pm (UTC)
(Link)
Хм. Не знаю, возможно, и я. Разница именно в том, что я знаю C и значение слова static, да. В питоне f(x=something) выглядит невинно, а делает совсем не то, что можно подумать.
From:nikolaypultsin
Date:May 5th, 2010 08:47 pm (UTC)
(Link)
Ну с точки зрения человека, не знающего C (тут я фантазирую) -- еще одно слово, что значит -- не знаю. Не иначе, оптимизация какая, типа register. Или ограничение, как volatile или restrict. Кто ж мог подумать, что оно ТАК меняет семантику! Уродство! (C)
[User Picture]
From:avysk
Date:May 5th, 2010 09:17 pm (UTC)
(Link)
Я тоже могу "спорить на любой стороне спора просто из удовольствия" (цитата из описания моего психологического типа) :-)
From:nikolaypultsin
Date:May 5th, 2010 09:29 pm (UTC)
(Link)
Да-да, в этом он (тип) у нас с тобой совпадает. :)
[User Picture]
From:gegmopo4
Date:September 30th, 2010 05:24 am (UTC)
(Link)
Вспомним еще фортран.
Unnkerr blog Powered by LiveJournal.com