JavaRush/ΠšΡƒΡ€ΡΡ‹/ΠœΠΎΠ΄ΡƒΠ»ΡŒ 1: Python Core/Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ сСриализациСй

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ сСриализациСй

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚Π°

10.1 ВсС Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎ-ΠΌΠΎΠ΅ΠΌΡƒ!

Иногда Π² Π²Π°ΡˆΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ… хранится ΠΌΠ½ΠΎΠ³ΠΎ ссылок Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ слуТСбныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎ сСти, ΠΈΠ»ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΏΠΎ сСти: ссылки Π½Π° Ρ„Π°ΠΉΠ»Ρ‹, Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Ρ‚.ΠΏ.

Π§Ρ‚ΠΎΠ±Ρ‹ сСриализация Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° ΠΈ Π² Ρ‚Π°ΠΊΠΈΡ… случаях, ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π»ΠΈ Π΄Π°Ρ‚ΡŒ классу Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ самому ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ своСй сСриализациСй. Для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹: __reduce__(), __getstate__(), __setstate__(). Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ сСриализованы ΠΈ восстановлСны.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ управляСмой сСриализации:

  • __reduce__(): Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ сСриализован.
  • __getstate__(): Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° для сСриализации.
  • __setstate__(self, state): ВосстанавливаСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· состояния.

НиТС я расскаТу ΠΎ Π½ΠΈΡ… ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅, ΠΈ ΠΊΠ°ΠΊ ΠΈΡ… вмСстС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ.

10.2 ΠœΠ΅Ρ‚ΠΎΠ΄ __reduce__()

ΠœΠ΅Ρ‚ΠΎΠ΄ __reduce__() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ сСриализован ΠΈ дСсСриализован. ΠšΠΎΡ€Ρ‚Π΅ΠΆ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ содСрТит:

  • Бсылку Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ»ΠΈ класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для восстановлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • ΠšΠΎΡ€Ρ‚Π΅ΠΆ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ класса.
  • Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ).

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value

    def __reduce__(self):
        return (self.__class__, (self.value,))

    def __repr__(self):
        return f"CustomClass(value={self.value})"

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
obj = CustomClass(42)

# БСриализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
serialized_obj = pickle.dumps(obj)
print("Π‘Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", serialized_obj)

# ДСсСриализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
deserialized_obj = pickle.loads(serialized_obj)
print("ДСсСриализованный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", deserialized_obj)

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ функция __reduce__() ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅:

class CustomClass:
    def __init__(self, value):
        self.value = value

    def __reduce__(self):
        # ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ класса
        cls = self.__class__
        # АргумСнты конструктора
        args = (self.value,)
        # БостояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
        state = self.__dict__
        return (cls, args, state)

Она Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ, состоящий ΠΈΠ· Ρ‚Ρ€Ρ‘Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²:

  • Бсылка Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ класс
  • АргумСнты конструктора (ΠΊΠΎΡ€Ρ‚Π΅ΠΆ)
  • Бсылка Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

Если вас Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ устраиваСт β€” __reduce__() ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ.

10.3 Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись состояния

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ __getstate__() ΠΈ __setstate__()

Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для управлСния состояниСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²ΠΎ врСмя сСриализации ΠΈ дСсСриализации.

  • __getstate__(): Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ сСриализовано.
  • __setstate__(self, state): ВосстанавливаСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· состояния.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

Допустим, ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π½Π΅ всС поля ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π° ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π½ΠΈΡ…. Для этого Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ __getstate__() Π½ΡƒΠΆΠ½ΠΎ:

  1. Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (Π·Π°Π΄Π°Π½Π½ΠΎΠ΅ слуТСбным ΠΏΠΎΠ»Π΅ΠΌ __dict__) Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ β€” ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ state.
  2. Π£Π΄Π°Π»ΠΈΡ‚ΡŒ ΠΈΠ· Π½Π΅Ρ‘ всС поля, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ.
  3. Π’Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠ°ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ __getstate__().
import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value
        self.internal_state = "internal"

    def __getstate__(self):
        state = self.__dict__.copy()
        del state['internal_state']  # Π˜ΡΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ состояниС
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        self.internal_state = "restored internal"  # ВосстанавливаСм Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ состояниС

    def __repr__(self):
        return f"CustomClass(value={self.value}, internal_state={self.internal_state})"

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
obj = CustomClass(42)
print("ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", obj)

# БСриализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
serialized_obj = pickle.dumps(obj)
print("Π‘Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", serialized_obj)

# ДСсСриализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
deserialized_obj = pickle.loads(serialized_obj)
print("ДСсСриализованный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", deserialized_obj)

ΠŸΡ€ΠΈ дСсСриализации, Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ __setstate__(), ΠΌΡ‹ Π΄Π΅Π»Π°Π΅ΠΌ Π΄Π²Π΅ Π²Π΅Ρ‰ΠΈ:

  1. ОбновляСм Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° update().
  2. ПолС internal_state (ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ нСсСриализуСмыС поля) ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ Π½ΠΎΠ²Ρ‹Π΅ значСния.
2
Π—Π°Π΄Π°Ρ‡Π°
ΠœΠΎΠ΄ΡƒΠ»ΡŒ 1: Python Core,  12 ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ9 лСкция
НСдоступна
ИспользованиСС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° reduce()
ИспользованиСС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° reduce()
2
Π—Π°Π΄Π°Ρ‡Π°
ΠœΠΎΠ΄ΡƒΠ»ΡŒ 1: Python Core,  12 ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ9 лСкция
НСдоступна
Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ нСсСриализуСмых ΠΏΠΎΠ»Π΅ΠΉ
Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ нСсСриализуСмых ΠΏΠΎΠ»Π΅ΠΉ
ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ (1)
  • популярныС
  • Π½ΠΎΠ²Ρ‹Π΅
  • старыС
Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ
Π‘Π΅ΠΌΡ‘Π½
Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ 14
10 сСнтября, 11:40
Π’ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ Ρ€Π°Π· Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ, Ρ‚ΠΎ Ρ‡Π΅Π³ΠΎ Π½Π΅Ρ‚ Π² Π»Π΅ΠΊΡ†ΠΈΠΈ, просто класс