Я смотрел исходный код встроенного argparse._AppendAction, который реализует действие "append"
и озадачен способ его реализации:
def __call__(self, parser, namespace, values, option_string=None):
items = _copy.copy(_ensure_value(namespace, self.dest, []))
items.append(values)
setattr(namespace, self.dest, items)
Чтобы разбить его:
-
_ensure_value
соответствует атрибутамdict.setdefault
. То есть, еслиnamespace
имеет атрибут с именемself.dest
, тогда он возвращается, если он не установлен на[]
и не возвращается. -
_copy.copy(x)
возвращает только мелкую копию. Когдаx
- это список, он точно какlist(x)
(но медленнее). - Затем элемент добавляется к копии списка, полученного из
namespace
. - Наконец, атрибут
self.dest
namespace
перезаписывается копией, что должно привести к сбою старого списка.
Почему это происходит в таком круговом и неэффективном способе, отбрасывая весь список для каждого добавления? Почему этого недостаточно?
def __call__(self, parser, namespace, values, option_string=None):
items = _ensure_value(namespace, self.dest, [])
items.append(values)