pythonapi设计模式问题
我经常发现我的类实例是其他类实例的后代,以类似于树的方式。例如,假设我正在用Python制作一个CMS平台。我可能有一个领域,下面是一个博客,下面是一篇文章。每个构造函数都将其父级作为第一个参数,以便知道它属于什么。可能是这样的:pythonapi设计模式问题,python,Python,我经常发现我的类实例是其他类实例的后代,以类似于树的方式。例如,假设我正在用Python制作一个CMS平台。我可能有一个领域,下面是一个博客,下面是一篇文章。每个构造函数都将其父级作为第一个参数,以便知道它属于什么。可能是这样的: class Realm(object): def __init__(self, username, password) class Blog(object): def __init__(self, realm, name) class Post(o
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)
class Realm(object):
def __init__(self, username, password):
...
def createBlog(self, name):
return Blog(self, name)
我通常会在父类中添加一个create方法,这样链接会更加自动。我的领域类可能如下所示:
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)
class Realm(object):
def __init__(self, username, password):
...
def createBlog(self, name):
return Blog(self, name)
这允许API用户不必导入每个模块,只导入顶层模块。可能是这样的:
realm = Realm("admin", "FDS$#%")
blog = realm.createBlog("Kittens!")
post = blog.createPost("Cute kitten", "Some HTML blah blah")
问题是那些create方法是冗余的,我必须在两个地方对相同的参数进行pydoc
我想知道是否有一种模式(可能使用元类)将一个类实例链接到父类实例。我可以这样调用代码,让博客知道它的父域是什么:
realm = Realm("admin", "FDS$#%")
blog = realm.Blog("Kittens!")
您可以为具有
add()
方法的容器使用公共基类
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
并使派生类中的parent
参数为可选
class Blog(Container):
def __init__(self, name, realm=None):
Container.__init__(realm)
self.name = name
上面的代码现在可以读取了
realm = Realm("admin", "FDS$#%")
blog = realm.add(Blog("Kittens!"))
post = blog.add(Post("Cute kitten", "Some HTML blah blah"))
您将不再有任何create…()
方法,因此无需两次记录任何内容
如果设置父项不仅仅涉及修改parent
属性,那么可以使用属性或setter方法
编辑:正如您在下面的评论中指出的,孩子们应该在CONSTRUCTOR的末尾与父母联系在一起。可以修改上述方法以支持这一点:
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")
像这样的东西怎么样,只是子类化它。在我的领域构造函数中:
class Realm(object):
def __init__(self, username, password):
...
parent = self
original_constructor = blog.Blog.__init__
class ScopedBlog(blog.Blog):
def __init__(self, *args):
self.parent = parent
original_constructor(self, *args)
self.Blog = ScopedBlog
似乎有效。它可以用基类或元类来概括。你的意思是实例是彼此的后代。有那么一会儿,我以为你在重新发明OOP。你是对的,我更新了这个问题。这是可行的,但我在想办法在构造函数运行结束时将它们结合起来。因此,如果没有父对象,博客甚至不能暂时存在(可能会引发类似“无法直接构造,请从父对象的上下文构造它”之类的异常)。您的add方法需要在此处返回子对象。当前add没有返回任何内容,因此行blog=realm.add(..)将导致blog==None@darkporter:编辑我的答案以反映这一点。嗯,我喜欢这样。它为您提供双向链接,以便您可以迭代您的孩子。让我来玩。答案被接受。在这种情况下,我将从构造函数参数中删除父对象。我要检查的只是一个通用的“家长”财产。