我正在尝试使用类对象的函数来创建新的类对象并遇到问题。这是我到目前为止的代码:
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)
吐出'room1',但前两个不起作用,因为room2作为变量尚未定义,而最后一个不起作用,因为它似乎是在创建一个新对象而不是引用现有的,所以只打印默认的“无”。
是否存在一种引用现有对象而没有设置变量的方法?或者我唯一的选择是做这样的事情?
def north(self,room):
roomDict[room] = Room(room)
self.N = roomDict[room]
self.N.S = self
编辑:我意识到我应该调用新的Room的south()函数而不是直接更改S变量,但这看起来很直观,因为它会导致循环,所以我还没有触及它。 / em>的
答案 0 :(得分: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的解决方案中一样,只需添加两行:
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
内嵌套Room
。如果你愿意,你可以把它变成一个外部词典。将注册表作为类属性的优点是,Room
对象可以在不知道其全局名称的情况下以self.registry
的形式访问它。 (轻微)的缺点是,每次访问时,您都需要输入Room.registry
或someroom.registry
,而不仅仅是registry
。
答案 1 :(得分:0)
你的dict解决方案可以起作用。使用类级roomDict
和new
构造函数不创建由其名称引用的现有对象:
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):
...
之后你可以将room2称为Room('room2')
。