Python API design pattern question -
i find have class instances descendants of other class instances, in tree fashion. example i'm making cms platform in python. might have realm, , under blog, , under post. each constructor takes it's parent first parameter knows belongs to. might this:
class realm(object): def __init__(self, username, password) class blog(object): def __init__(self, realm, name) class post(object); def __init__(self, blog, title, body)
i typically add create method parent class, linkage bit more automatic. realm class might this:
class realm(object): def __init__(self, username, password): ... def createblog(self, name): return blog(self, name)
that allows user of api not import every single module, top level one. might like:
realm = realm("admin", "fds$#%") blog = realm.createblog("kittens!") post = blog.createpost("cute kitten", "some html blah blah")
the problem create methods redundant , have pydoc same parameters in 2 places.
i wonder if there's pattern (perhaps using metaclasses) linking 1 class instance parent class instance. way call code , have blog know it's parent realm is:
realm = realm("admin", "fds$#%") blog = realm.blog("kittens!")
you use common base class containers featuring add()
method
class container(object): def __init__(self, parent=none): self.children = [] self.parent = parent def add(self, child) child.parent = self self.children.append(child) return child
and make parent
parameter optional in derived classes
class blog(container): def __init__(self, name, realm=none): container.__init__(realm) self.name = name
your code above read
realm = realm("admin", "fds$#%") blog = realm.add(blog("kittens!")) post = blog.add(post("cute kitten", "some html blah blah"))
you wouldn't have create...()
methods more, no need document twice.
if setting parent involves more modifying parent
attribute, use property or setter method.
edit: pointed out in comments below, children should tied parents end of contstructor. above approach can modified support this:
class container(object): def __init__(self, parent=none): self.children = [] self.parent = none def add(self, cls, *args) child = cls(self, *args) self.children.append(child) return child class realm(container): def __init__(self, username, password): ... class blog(container): def __init__(self, realm, name): ... class post(container): def __init__(self, blog, title, body): ... realm = realm("admin", "fds$#%") blog = realm.add(blog, "kittens!") post = blog.add(post, "cute kitten", "some html blah blah")
Comments
Post a Comment