Конвертировать python attr.ib, используя другие значения - PullRequest
1 голос
/ 23 января 2020

Я использую библиотеку attrs для создания структуры данных для путей. Я хочу, чтобы первым атрибутом был каталог root, к которому автоматически присоединяются другие атрибуты. Я хотел бы иметь что-то вроде этого:

def my_converter(obj, value):
  return os.path.join(obj.root, value)

class Paths:
  root = attr.ib()
  relative = attr.ib(converter=my_converter)

Это бы сработало, но функция converter получает только один аргумент. Есть ли чистый способ преобразования значения с использованием других атрибутов перед проверкой? validator принимает три аргумента (один из которых является объектом), но он не является подходящим местом для преобразования значений. Кроме того, помещение всего в __attrs_post_init__ отрицает цель использования атрибутов.

1 Ответ

1 голос
/ 28 января 2020

Вы можете использовать третий атрибут и значение по умолчанию:

import os
import attr

@attr.s
class Paths:
  root = attr.ib()
  _relative = attr.ib(repr=False)
  full = attr.ib()

  @full.default
  def _full_factory(self):
     return os.path.join(self.root, self._relative)

, что дает вам:

>>> Paths("/home", "foo")
Paths(root='/home', full='/home/foo')

Я лично предпочитаю прямые и хорошо названные @classmethod фабричные методы в таких случаях Они, как правило, более читабельны, и их можно легко избежать при написании тестов.

...