Pull to refresh

Comments 20

UFO just landed and posted this here
Эм… Создавать свой класс только ради того, чтобы складывать хеши? Мне честно говоря эта идея не нравится. Имхо лучше написать функцию joinDict( *args ). Это будет более читабельно для человека, который первый раз видит ваш код. Честно говоря если я бы увидел код например
def someFunc( val1, val2 ):
    ...
    val3 = val1 + val2

я бы точно не подумал что val1 и val2 это словарь. Соответственно читабельность ухудшается.
В общем думайте сами )
Спасибо за комментарий.
Складывать это только одно из возможных действий — создав такую обертку для словарей, в будущем с ними можно будет делать много всего.
Насчет читаемости с первого взгляда, вы пожалуй правы.
чем ближе код программы к предметной области, тем легче он читается.
Если я код вижу впервые, то мне по-большему счету, совершенно пофиг, это хеши, список кортежей или еще что-либо. Сложение я по-любому пойму однозначно — из двух «нечто» делается одно «нечто».
А зачем все это шаманство? Неужели подобный функционал настолько востребован, чтобы уделять этому особое внимание?

Кстати, я бы не назвал это синтаксическим сахаром ;)

Если бы вы сказали, что можно написать в одну строчку так
values = global_config.copy().update(local_config).update(db_row).update(user_info)
то это было бы большим сахарком.
Если конечно язык это позволяет (я не пишу на Python).
А так вы просто написали, что в Python есть перегрузка операторов и не более :)

И это не для удобства чтения, это для удобства записи. Т.к. операции сложения для хешей не предусмотрено, читающему придется разбираться как это работает, а это, по-моему, не упростит, а, скорее, усложнить чтение ;)
А зачем все это шаманство? Неужели подобный функционал настолько востребован, чтобы уделять этому особое внимание?…
А так вы просто написали, что в Python есть перегрузка операторов и не более :)

По сути да, описан простой и удобный вариант переопределить оператор для какого-либо объекта :)
Мне это показалось удобно в моем проекте. Кроме того, краткое введение в «секретные» __ методы в питоне :)

values = global_config.copy().update(local_config).update(db_row).update(user_info)

В том-то и проблема, что нельзя — update обновляет словарь на месте, но ничего не возвращает — поэтому такая цепочка не работает :( Собственно, это один из стимулов к созданию сложения :)

Думаю, тогда логично было бы перегрузить update, чтобы он принимал несколько параметров. В этом случае и читаемость не ухудшится, и спорных ситуаций не будет.
Тоже вариант.
Но надо сохранить совместимость и не сломать другие места программы, которые расчитывают на старое поведение.
Ну если update в «родном» виде принимает только один параметр, то это не сломает других мест ;) Расширение обычно ничего не ломает.
Конечно, не надо перегружать стандартные операторы. Тем более делать сложение некоммутативным.

values = global_config.copy()
for other_values in (local_config, db_row, user_info): values.update(other_values)
«Понятно, что собственно сложения ассоциативных массивов (они же хеши, dict-ы и т.п. в разных языках) не существует» <<<

Кто вам такое сказал??? o_O
Perl: стандартная конструкция:
%a = ( 'aa' => 1, 'ab' => 2 );
%b = ( 'bb' => 3, 'ab' => 4 );

%c = ( %a, %b ); # %c = ( 'aa' => 1, 'ab' => 4, 'bb' => 3 );

И никакого шаманства… :-)
Ну, перл это совсем другой язык, и совсем другие плюшки.
И я не сказал бы, что это можно назвать сложением хешей :)
И плюс к этому, у нас тут нет оператора «+», который «облегчит» непонимание кода.
UFO just landed and posted this here
Если уже делать что-то подобное, то через monkey patching, чтобы можно было эти операции выполнять со стандартными классами ассоциативных массивов.
UFO just landed and posted this here
Monkey patching вообще очень спорная вещь, я бы не рекомендовал этим пользоваться, только в каких-то крайних случаях. Но если уж мне приспичило бы сделать так, чтобы ассоциативные массивы умели складываться, я бы предпочел прикрутить это к стандартным классам.
Не люблю сильно менять поведение стандартных классов, т.к. очень многое на это может быть завязано, а значит, могут вылезти «труднодебагируемые» ошибки в самых разных местах. Если не сейчас, то в будущем, когда выйдет новая версия языка.
Не думаю, что такое изменение, что нибудь сильно сломает.

>>> from UserDict import UserDict
>>> UserDict._update = UserDict.update
>>> UserDict.update = lambda self, new: self._update(new) or self
>>> a = UserDict( {'a':1,'b':2} )
>>> b = UserDict( {'b':3,'d':4} )
>>> c = UserDict( {'c':5} )
>>> a.copy().update( b ).update( c )
{'a': 1, 'c': 5, 'b': 3, 'd': 4}
>>> 
UFO just landed and posted this here
На Ruby имхо куда красивее:
class Hash
  def +(hash)
    self.reverse_merge(hash)
  end
end
{:a => 1}+{:b=>2} # => {:a=>1, :b=>2}
Sign up to leave a comment.

Articles