2016-02-14 73 views
1

我試圖使用類對象的函數來創建一個新的類對象並遇到問題。下面的代碼我到目前爲止:如何引用沒有定義變量的現有類對象?

class Room(object): 
    def __init__(self, name): 
     self.name = name 
     self.N = None 
     self.E = None 
     self.S = None 
     self.W = None 
    '''relevant code''' 
    def north(self,room): 
     self.N = Room(room) 
     self.N.S = self 
    def south(self,room): 
     self.S = Room(room) 
     self.S.N = self 

所以我想這些打印語句

room1 = Room('room1') 
room1.north('room2') 

print(room2.S) 
print(Room(room2).S) 
print(Room('room2').S) 

吐出「會議室1」中的至少一個,但前兩千萬不要因爲房間2作爲工作一個變量還沒有定義,最後一個不起作用,因爲它似乎在創建一個新的對象而不是引用現有的對象,所以它只是打印默認的'None'。

確實存在一種方法來引用一個沒有設置變量的現有對象嗎?或者是我唯一的選擇做這樣的事情?

def north(self,room): 
     roomDict[room] = Room(room) 
     self.N = roomDict[room] 
     self.N.S = self 

編輯:我知道我可能應該調用新的房間的南面()函數,而不是直接改變s變量,但似乎直觀地像它會導致一個循環,所以我沒有觸摸它呢。

回答

1

*基於OP的澄清編輯*

如果您有大量的要指沒有他們結合變量的對象,dict是要走的路。

您可以使用@Berci的解決方案。但請注意,使用該解決方案時,如果您已擁有一個名爲foo的房間,則不能通過再次簡單地撥打Room('foo')來覆蓋該房間 - 這樣做只會返回原始foo房間。要覆蓋現有房間,您必須首先執行del Room.roomDict['foo'],然後致電Room('foo')。這可能是你想要的,但也許不是。

實現以下是不太稀奇,並且不需要__new__(事實上,Berci的解決方案不需要任何__new__,可以在__init__將全部完成):

class Room: 
    registry = {} 
    def __init__(self, name): 
     self.registry[name] = self 
     # the rest of your __init__ code 

如果你讓會議室成爲覆蓋禁止,因爲他們在Berci的解決方案,只需添加兩行:內部Room

class Room: 
    registry = {} 
    def __init__(self, name): 
     if name in self.registry: 
      raise ValueError('room named "{}" already exists'.format(name)) 
     self.registry[name] = self 

這是沒有必要窩registry。如果你願意,你可以把它作爲外部字典。將註冊表作爲類屬性的好處是您的對象可以在不知道其全局名稱的情況下以self.registry的身份訪問它。 (輕微)缺點是您每次訪問它時都需要輸入Room.registrysomeroom.registry而不是僅僅輸入registry

+0

這裏的問題是會有很多其他的房間,所以如果我不能直接引用他們,我會最終稱他們爲 room1.N.E.W.N.S 或者荒謬的事情。 – aryst0krat

+0

@ aryst0krat那麼這個問題的大背景是什麼?根據你想要對房間做什麼,可能有更好的方法來組織它們,但我需要知道你想和他們一起來幫助。 – gil

+0

更大的背景是它是基於文本的冒險遊戲。就我的Room對象而言,我需要能夠引用它們來告訴玩家所在的位置,遊戲對象的位置等等。所以能夠通過名稱來引用它們是重要的,但我寧願不必爲他們全部手動創建變量。 他們連接的原因只是從一個房間移動到另一個房間。所以如果你說要向北移動,它會將你移動到房間的N變量中的房間。 – aryst0krat

0

您的字典解決方案可以起作用。使用一類級別roomDictnew構造不創建它的名字提到一個已經存在的對象:

class Room(object): 
    roomDict = {} 
    def __new__(cls, name): 
     if name in cls.roomDict: 
      return cls.roomDict[name] 
     self = object.__new__(cls, name) # here the object is created 
     cls.roomDict[name] = self 
     return self 
    def __init__(self, name): 
     ... 

所以,你可以參考一下房間2爲Room('room2')之後。

+0

我認爲這個實現可能高於我目前的技能水平哈哈。我不認識'cls'或瞭解\ _ \ _ new \ _ \ _函數(它看起來像是內置的函數)是如何被調用的,或者爲什麼它會與\ _ \ _ init \ _ \ _不同,也不像整個功能那樣完全。儘管如此,如果沒有別的東西肯定會記住它的未來,我會試着去解決它。 – aryst0krat

相關問題