Допустим, у нас реализовано запоминание свойства.
@property
def thing(self):
if self._thing is MISSING:
self._thing = self._calc_thing()
return self._thing
Условие гонки существует, поскольку две функции могут выполнять thing()
.Однако, поскольку это «функционально чистая» операция (конечный результат в основном тот же, за исключением некоторой дополнительной работы и создания второго идентичного объекта, который имеет второй идентификатор объекта), мы можем, если пожелаем, с помощью дизайна, игнорируй это.Я в порядке с этим, давайте предположим, что все в порядке.Это все круто.
Итак, Я думаю это безопасное, без блокировки запоминание с допущениями:
- назначение является атомным
_calc_thing()
чисто __setattribute__
не переопределяется - нас не волнует уникальность объекта
id
результата thing
(поскольку могут быть созданы два объекта)
Теперь неудобно определять self._thing
и рассматривать две разные дополнительные реализации:
1)
@property
def thing(self):
x = self._cache.get("thing", MISSING)
if x is MISSING:
x = self._calc_thing()
self._cache["thing"] = x # Safe?
return x
2)
@cached property
def thing(self):
return self._calc_thing()
с
class cached_property(object):
def __init__(self, factory_method):
self._attr_name = factory_method.__name__
self._factory_method = factory_method
def __get__(self, instance, owner):
attr = self._factory_method(instance)
# Is this thread safe?
setattr(instance, self._attr_name, attr) # Replace the property attribute with a value attribute.
return attr
Являются ли 1) и 2) потокобезопасными?
1) основывается на безопасности потоков new словарь дополнений.Могут ли два потока безопасно добавить в словарь , если нам не нужно упорядочивать ?
2), опираясь на поточную безопасность обновлений словаря атрибутов объекта.(может быть)
Есть похожие статьи:
Тем не менее, я все еще не уверен, действительно ли 1) или 2)сейф.