В документации по Attrs Python, в разделе Автоматическое преобразование и модификация полей говорится:
...Вы можете добавлять конвертеры, изменять типы и даже удалять атрибуты. полностью или создать новые!» (курсив наш).
В документации API относительно атрибута также говорится: «Вы никогда не должны создавать экземпляр этого класса самостоятельно».
Однако если вы попытаетесь добавить поле в функцию field_transformer
, вы не сможете этого сделать, по крайней мере, с помощью функции attrs.field()
.
import attrs
def transformer(cls, fields):
fields.append(attrs.field(name='bar'))
return fields
@attrs.define(field_transformer=transformer)
class A:
pass
A(bar=1)
Это не удается с помощью TypeError: field() got an unexpected keyword argument 'name'
. Если вместо этого вы используете «псевдоним», вы получите AttributeError: '_CountingAttr' object has no attribute 'name'
.
Как правильно добавить поле в функцию field_transformer
?
Редактировать: Мне удалось заставить работать следующее:
import attrs
def transformer(cls, fields):
ca = attrs.field()
f = attrs.Attribute.from_counting_attr(name = "foo", ca=ca, type=int)
return [f, *fields]
@attrs.define(field_transformer=transformer)
class A:
pass
A(foo=1)
attrs
Вот еще один способ добавления поля в класс с помощью attrs.
from attrs import define, field, make_class
class Foo:
pass
Foo = make_class(Foo.__name__, {'bar': field(alias='bar')},
bases=(Foo,), field_transformer=None)
foo = Foo(bar=1)
foo # Foo(bar=1)
В качестве альтернативы, если в вашем классе уже определены другие атрибуты, будет работать следующее.
@define()
class Foo:
foo: int
Foo = make_class(Foo.__name__, {'bar': field(alias='bar')},
bases=(Foo,), field_transformer=None)
foo = Foo(foo=10, bar=1)
foo # Foo(foo=10, bar=1)
ПРИМЕЧАНИЕ. Если вам необходимо использовать функцию преобразования (скажем,
transformer_func
), используйтеfield_transformer=transformer_func
внутри функцииmake_class
.
@ slaughter98: Вот еще один способ получить то, что вы искали.
Я добавил дополнительную информацию о создании конвертера внутри функции field_transformer: stackoverflow.com/q/78339197/1088076