我正在写与代表的网页,如内容的各种类网站发生器Page
,NewsPost
,Tag
,Category
等。
我希望能够简单地构造这些对象,对此我没有任何问题。
但是,我也想在特定的上下文中构造这些对象-例如,具有特定根URL的网站的上下文。假设我将此上下文放入类的实例中ContentManager
。这是我最终希望最终得到的代码:
page = Page(title='Test Page', content='hello world!')
assert page.cm == None
cm = ContentManager(root_url='//localhost')
page = cm.Page(title='Test Page', content='hello world!')
assert page.cm == cm
如果page.cm
在中设置了每个实例属性__init__
,我可以轻松地进行管理,但是我需要调用cm.Page
需要访问该cm
对象的类方法,因此它必须是静态属性。
如果仅将其设置为类的静态属性Page
,则最终也会影响其他 ContentManager
页面,这是不希望的。
我将如何实现呢?元类?还是某种类工厂功能?
一种解决方案是Page
为每个ContentManage
实例创建的子类:
class Page:
cm = None
def __init__(self, title, content):
self.title = title
self.content = content
class ContentManager:
def __init__(self, root_url):
class PerContentManagerPage(Page):
cm = self
self.Page = PerContentManagerPage
page0 = Page(title='Test Page', content='hello world!')
cm = ContentManager(root_url='//localhost')
page = cm.Page(title='Test Page', content='hello world!')
cm2 = ContentManager(root_url='//localhost')
page2 = cm2.Page(title='Test Page 2', content='hello world!')
assert page0.cm is None
assert page.cm == cm
assert page2.cm == cm2
在python中,类也是对象(其元类的实例)。此解决方案在Page
每次实例化时都会创建一个新的子类ContentManager
。这意味着cm.Page
该类与cm2.Page
该类不同,但两者都是的子类Page
。这就是为什么cm.Page.cm
和可能cm2.Page.cm
具有不同的值的原因,因为它们是两个单独的类(或类对象)。
注意:尽管在python中,这可以通过动态创建子类对象来解决,但问题通常具有更好的解决方案。动态创建类/子类是一个警告标志(HACK)。
我仍然坚信您不应该为每个内容管理器实例创建一个页面子类。取而代之的是,我将简单地使用全局实例ContentManager
和Page
类的实例,方法是通过适当的方式将它们与彼此的引用连接起来,并将数据和代码放入实例属性/方法中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句