在 attrs 中更改冻结 class 的属性
Changing an attribute of a frozen class in attrs
import attr
@attr.s(slots=True, frozen=True)
class C:
url = attr.ib(type=str)
x = attr.ib()
y = attr.ib()
z = attr.ib(default=10)
@y.default
def _any_name_except_a_name_of_an_attribute(self):
return self.x + 1
@url.validator
def map_url(self, attribute, value):
if value == "apple":
self.url = "mango"
print(C(x=4,y=5, url="apple"))
我希望找到一种方法来在 url 初始化为特定值时更改它,而不会丢失 class 的冻结 属性,这是否可行?
更改传入的值是 converter 的用途:
url = attr.ib(type=str, converter=lambda x: 'mango' if x=='apple' else x)
或者,这可以实现 post-使用 attr.evolve 方法进行初始化,该方法创建实例的副本并应用指定的更改,从而保持对 class 实例。
顺便说一句,这种对不可变实例的修改在函数式编程中比比皆是,比如scala的案例class copy method.
>>> c = C(x=4, y=5, url="apple")
# create a new instance with a different url
>>> attr.evolve(c, url="banana")
C(url='banana', x=4, y=5, z=10)
# original instance remains unchanged
>>> c
C(url='apple', x=4, y=5, z=10)
import attr
@attr.s(slots=True, frozen=True)
class C:
url = attr.ib(type=str)
x = attr.ib()
y = attr.ib()
z = attr.ib(default=10)
@y.default
def _any_name_except_a_name_of_an_attribute(self):
return self.x + 1
@url.validator
def map_url(self, attribute, value):
if value == "apple":
self.url = "mango"
print(C(x=4,y=5, url="apple"))
我希望找到一种方法来在 url 初始化为特定值时更改它,而不会丢失 class 的冻结 属性,这是否可行?
更改传入的值是 converter 的用途:
url = attr.ib(type=str, converter=lambda x: 'mango' if x=='apple' else x)
或者,这可以实现 post-使用 attr.evolve 方法进行初始化,该方法创建实例的副本并应用指定的更改,从而保持对 class 实例。
顺便说一句,这种对不可变实例的修改在函数式编程中比比皆是,比如scala的案例class copy method.
>>> c = C(x=4, y=5, url="apple")
# create a new instance with a different url
>>> attr.evolve(c, url="banana")
C(url='banana', x=4, y=5, z=10)
# original instance remains unchanged
>>> c
C(url='apple', x=4, y=5, z=10)