2013-03-05 101 views
0

外部類考慮這段代碼:訪問來自內部蟒蛇

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() 

我所試圖做的似乎有點不合法的。不過,我相信有一種方法可以做到。好像我可能必須重寫得到方法的地方。非常感謝您的幫助!

這裏是辦法,我打算用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 

我編輯現在編碼到工作版本。感謝大家這樣快速的輸入!你們好棒!仍然可能不是最好的方法,但我現在還想不出另一種解決方法。

+1

[PEP-8](http://www.python.org/dev/peps/pep-0008/#class-names)建議只使用'CapWords'作爲類名 - 它使代碼更具可讀性。同樣,它建議不要排列作業。這裏也沒有外部或內部類(儘管這樣的概念在Python中無關緊要)。 – 2013-03-05 22:41:40

+0

它已經可以工作了,只需添加一個'self'參數即可。 – 2013-03-05 22:42:51

+0

@MartijnPieters它不會,你需要一個'Pages'的實例 - 你不能透過這個類。 – 2013-03-05 22:43:43

回答

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

+0

它的工作原理是唯一的,它因爲某種原因選擇了所有的東西 – Barmaley 2013-03-05 23:00:53

+0

不,不與這個答案中的代碼不同。查看演示會話;當選擇'faq'時,'.index.selected'爲False。 – 2013-03-05 23:08:57

+0

如何僅使用代碼運行演示會話? – Barmaley 2013-03-05 23:28:14

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 , ] 

注意,這讓你有多個Pagesets的能力,你要找的類的實例。你上面的代碼引用了類本身(這是沒有理由的)。我把self.pages作爲一個屬性,因爲你可能想要在頁面集中存儲其他數據。

+0

'.select()'方法的'self'參數在哪裏?您正在使用同名的屬性來遮蓋該方法。 – 2013-03-05 22:51:04

+0

謝謝。我只是打字速度很快。這是一個非常尷尬的問題。我有點想刪除我的答案 - 因爲問題本身似乎有點倒退。 – 2013-03-05 22:52:09

0

我會在這裏認爲最好的解決辦法是將您select()方法移到Pages類:

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

對我來說,這似乎是它坐一個更合乎邏輯的地方,並且意味着Page實例不需要知道它們所屬的實例。

在保存所選頁面的Pages實例上簡單地擁有selected屬性可能更好,而不是每個Page知道它是否被選中,但取決於設計。

+0

我可以移動到頁面,但是如何從單個頁面觸發此類方法?我不斷收到TypeError:'bool'對象現在不可調用錯誤 – Barmaley 2013-03-05 23:12:32

+0

@ user2137711您不知道。重新構建你的程序不要依賴於它更有意義。 – 2013-03-05 23:18:53

+0

所以我要用它的方式是這樣的: – Barmaley 2013-03-05 23:31:09

0

頁面對象管理大量單獨的頁面對象。它應該對涉及它們的事情負責,例如,在你的示例中,將單個頁面標記爲選定的並且將其他標記放棄。

儘管您可能會讓每個頁面都意識到擁有它的Pages對象,但這樣做太多會很快導致混亂的意大利麪條代碼。

P.S. - 嘗試提出一些更好的名字,甚至談論有-S和是不舒服。