Sage Wiseman
Sage Wiseman

Reputation: 26

Python attrs library and referencing instance methods

How can I convert the class below to use the attrs library:

class MyClass(object):
    def __init__(self, api, template=None, **kwargs):
        self.api = api
        self.param1 = param1
        if template is not None:
            self.template = api.get_template(desc=template)

Specifically, how do I deal with the dependency of one parameter on the initialization of another? In my initial attempt, I started with a class like this:

@attr.s
class MyAttrClass(object):
    api = attr.ib()
    param1 = attr.ib()

But I am unsure of how to deal with the template attribute? My initial thought was to do:

def __attrs_post_init__(self):
    self.template = api.get_template(desc=template)

I am wondering if there is a better way to accomplish this, though?

Upvotes: 0

Views: 628

Answers (2)

I think the takes_self argument to Factory may be useful to you.

One problem I think I see here is that you are taking an argument called template with looks like it's a different kind of thing (perhaps a str) than what you set as self.template (perhaps a Template). I suggest you give those different names, and then do something like this:

from attr import Factory, attrib, attrs
from attr.validators import instance_of

from my.code import API, Template

@attrs
class Foo(object):
    api = attrib(validator=instance_of(API))

    _template_name = attrib(validator=instance_of(str))

    template = attrib(
        validator=instance_of(Template),
        default=Factory(
            lambda self: self.api.get_template(self._template_name)
        ),
        takes_self=True,
        init=False,
    )

Upvotes: 1

innov8
innov8

Reputation: 2219

'param1' from your question is hard to follow, and I can only assume it is to come from 'kwargs'?

@attr.s
class MyAttrClass(object):
    api = attr.ib()
    template = attr.ib(default=None)
    param1 = attr.ib()

    def __attrs_post_init__(self):
        if self.template is not None:
            self.template = api.get_template(desc=template)

should be a workable solution to deal with the template attribute, but what i am yet to resolve is how to deal with the kwargs. I am looking into that myself, so will post a solution once i discover one.

Upvotes: 0

Related Questions