从内部python访问外部类

时间:2013-03-05 22:40:30

标签: python class outer-join

考虑这段代码:

class Page(object):
  def __init__(self, name, title):
    self.name   = name
    self.title  = title
    self.selected = False
  def select(self):                 <-- How can I make this method work?
    for Page in Pages:
        Page.selected = False
    self.selected = True
class Website(object):
  def __init__(self):
    self.index    = Page("index", "Home")
    self.settings = Page("settings", "Settings")
    self.users    = Page("users", "Users")
    self.logs     = Page("logs", "Logs")
    self.faq      = Page("faq", "FAQ")
  def __iter__(self):
    return iter([self.index, self.settings, self.users, self.logs, self.faq])
Pages = Website()

我想做的事情似乎有些违法。不过,我确信有办法做到这一点。好像我可能要在某处重写 get 方法。非常感谢你的帮助!

以下是我打算使用Bottlepy使用这些类的方法:

设置页面:

@route('/')
@route('/<selectedPage>')
@route('/<selectedPage>/')
def dynamic_routing(selectedPage='index'):
  for Page in Pages:
     if selectedPage == Page.name:
            Page.select()
  return template('default')

检索页面信息(在Bottlepy模板中):

%for Page in Pages:
    %if Page.selected:
        <title>{{Page.title}}</title>                
    %else:
        <title>Page Not Found</title>
    %end
%end

我现在已将代码编辑为工作版本。谢谢大家的快速输入!!!你们好棒!仍然可能不是最好的方法,但我现在想不出另一种方法来解决它。

4 个答案:

答案 0 :(得分:0)

将引用存储到pageset,然后遍历该集合中的页面

class Page(object):
  def __init__(self, name, title, pageset):
    self.name   = name
    self.title  = title
    self.pageset = pageset
  def select(self):
    for page in self.pageset.pages:
        page.select = False
    self.select = True

class Pageset(object):
  def __init__(self):
    self.index    = Page("index", "Home", self )
    self.settings    = Page("settings", "Settings", self )
    self.pages = [ self.index , self.settings , ]

请注意,这使您能够拥有多个Pageset,并且您正在查看类实例。上面的代码引用了类本身(实际上没有理由这样做)。我将self.pages作为属性,因为您可能希望将其他数据存储在页面集中。

答案 1 :(得分:0)

您需要重命名.select属性或.select()方法,并在方法中添加self参数,否则您的代码将起作用:

class Page(object):
    def __init__(self, name, title):
        self.name   = name
        self.title  = title
        self.selected = False

    def select(self):
        for Page in Pages:
            Page.selected = False
        self.selected = True

通过这些更改,您的代码可以正常运行:

>>> Pages = Pages()
>>> Pages.index
<__main__.Page object at 0x10a0b6cd0>
>>> Pages.index.selected
False
>>> Pages.index.select()
>>> Pages.index.selected
True
>>> Pages.faq.select()
>>> Pages.index.selected
False

然而,这并不是说这是一个很好的架构设计。我要说你需要将一个页面选择转移到Pages类,最重要的是避免用全局实例Pages替换类Pages

答案 2 :(得分:0)

我认为这里最好的解决方案是将select()方法转移到Pages类:

class Pages(object):
    ...
    def select(self, target):
        for page in self:
           page.select = False
        target.select = True

对我而言,这似乎是一个更合理的地方,并且意味着Page个实例不需要知道它们所属的Pages个实例。

在拥有所选页面的selected实例上简单地拥有Pages属性甚至可能更好,而不是每个Page知道它是否被选中,但这取决于设计。

答案 3 :(得分:0)

Pages对象管理许多单独的Page对象。它应该对涉及它们的所有内容负责,例如,在您的示例中,将单个页面标记为已选中并且展开其他页面。

虽然你可能会让每个页面都知道拥有它的Pages对象,但做太多这样的事情很快就会导致意大利面条代码混乱。

P.S。 - 尝试提出一些更好的名字,甚至谈论页面 -s和页面是不舒服的。