How best to initialize a class using an attribute from attrs?

Viewed 402

In vanilla Python to create a class which, when initiated, would also initiate another class I would use __init__(self):

class SomeClass:
    __init__(self, token: str):
        self.token = token
        client = WebClient(auth=self.token)

But in attrs, I can't do this. The following yields an error because it is passing a _CountringAttr object, not the resolved string.

@attr.s()
class SomeClass:
    token: str = attr.ib()
    client = WebClient(auth=token)

What is the "right" way of accomplishing this?

1 Answers

You can either use a default:

@attr.define
class SomeClass:
    token: str
    client: WebClient = attr.field()  # needed! attr.ib works too

    @client.default
    def _client_factory(self):
        return WebClient(self.token)

or __attrs_post_init__:

@attr.define
class SomeClass:
    token: str
    client: WebClient = attr.field(init=False)

    def __attrs_post_init__(self):
        self.client = WebClient(self.token)

P.S. I'm using the modern attrs APIs to make them more known. Check out https://www.attrs.org/en/latest/names.html if you want to know more.

Related