Reputation: 26
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
Reputation: 899
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
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