maxwell_rob33
maxwell_rob33

Reputation: 127

Is there a way to signal an attrs class field so it won't be part of deepcopy / pickle?

I find myself often writing attrs classes that looks something like this:

import attrs
from some_app import Client

@attrs.mutable
class Foo:
    _credentials: str = attrs.field(validator=attrs.validators.instance_of(str))
    _client: Client = attrs.field(
        init=False,
        validator=attrs.validators.instance_of(Client),
        default=attrs.Factory(lambda self: Client(self._credentials), takes_self=True),
    )

    def bla(self):
        return self._client.do_stuff

I'd like to know if there is a way to exclude the _client field from operations like deepcopying or pickling?

Thanks in advance!

Upvotes: 0

Views: 26

Answers (1)

vassiliev
vassiliev

Reputation: 653

You can rewrite __deepcopy__() method for your class and rebuild a new Class without properties you do not want to copy (_client in your case, and p_hidden in my example) by using type.

from copy import deepcopy
class ClassA(object):
    p_hidden = 1
    def __init__(self, value):
        self.p_shown = value

    def __deepcopy__(self, memodict={}):
        return type('ClassA', ClassA.__bases__, {k: v for k, v in ClassA.__dict__.items() if k != 'p_hidden'})(self.p_shown)

a = ClassA('some values')
print(a.p_shown)  # 'some values'
print(a.p_hidden)  # 1
b = deepcopy(a)
print(b.p_shown)  # 'some values'
# print(b.p_hidden)  # AttributeError: 'ClassA' object has no attribute 'p_hidden'

from pickle import dumps
c = dumps(a)
print(c)  # b'\x80\x03c__main__\nClassA\nq\x00)\x81q\x01}q\x02X\x07\x00\x00\x00p_shownq\x03X\x0b\x00\x00\x00some valuesq\x04sb.'

If you just do not want your class deepcopied, just define an empty __reduce__() method or a __deepcopy__() method, like:

from copy import deepcopy
class ClassA(object):
    p_hidden = 1
    def __init__(self, value):
        self.p_shown = value

    def __reduce__(self):  # or def __deepcopy__(self, memodict={}):
        pass

Upvotes: 0

Related Questions