我尝试了一些代码,但似乎导致了问题:
class Page:
cache = []
""" Return cached object """
def __getCache(self, title):
for o in Page.cache:
if o.__searchTerm == title or o.title == title:
return o
return None
""" Initilize the class and start processing """
def __init__(self, title, api=None):
o = self.__getCache(title)
if o:
self = o
return
Page.cache.append(self)
# Other init code
self.__searchTerm = title
self.title = self.someFunction(title)然后我试着:
a = Page('test')
b = Page('test')
print a.title # works
print b.title # AttributeError: Page instance has no attribute 'title'这段代码有什么问题?为什么它不能工作?有没有办法让它工作呢?如果不是,我该如何轻松、透明地访问最终用户缓存对象呢?
发布于 2012-10-25 01:31:02
如果您想要操作创建,则需要更改__new__。
>>> class Page(object):
... cache = []
... """ Return cached object """
... @classmethod
... def __getCache(cls, title):
... for o in Page.cache:
... if o.__searchTerm == title or o.title == title:
... return o
... return None
... """ Initilize the class and start processing """
... def __new__(cls, title, api=None):
... o = cls.__getCache(title)
... if o:
... return o
... page = super(Page, cls).__new__(cls)
... cls.cache.append(page)
... page.title = title
... page.api = api
... page.__searchTerm = title
... # ...etc
... return page
...
>>> a = Page('test')
>>> b = Page('test')
>>>
>>> print a.title # works
test
>>> print b.title
test
>>>
>>> assert a is b
>>> 编辑:使用__init__的
>>> class Page(object):
... cache = []
... @classmethod
... def __getCache(cls, title):
... """ Return cached object """
... for o in Page.cache:
... if o.__searchTerm == title or o.title == title:
... return o
... return None
... def __new__(cls, title, *args, **kwargs):
... """ Initilize the class and start processing """
... existing = cls.__getCache(title)
... if existing:
... return existing
... page = super(Page, cls).__new__(cls)
... return page
... def __init__(self, title, api=None):
... if self in self.cache:
... return
... self.cache.append(self)
... self.title = title
... self.api = api
... self.__searchTerm = title
... # ...etc
...
>>>
>>> a = Page('test')
>>> b = Page('test')
>>>
>>> print a.title # works
test
>>> print b.title
test
>>> assert a is b
>>> assert a.cache is Page.cache
>>> 发布于 2012-10-25 01:23:00
一旦创建了对象,您就不能真正更改它的实例。当将self设置为其他值时,您所要做的就是更改变量指向的引用,这样实际的对象就不会受到影响。
这也解释了为什么title属性不在那里。一旦更改了本地self变量,就会立即返回,从而阻止当前实例初始化title属性(更不用说此时的self不会指向正确的实例)。
因此,基本上,您不能在初始化期间更改对象(在__init__中),因为此时它已经被创建,并被分配给变量。像a = Page('test')这样的构造函数调用实际上与:
a = Page.__new__('test')
a.__init__('test')如您所见,首先调用的是__new__类构造函数,而这实际上是负责创建实例的人。因此,您可以重写类的__new__方法来操作对象创建。
但是,通常首选的方法是创建一个简单的工厂方法,如下所示:
@classmethod
def create (cls, title, api = None):
o = cls.__getCache(title)
if o:
return o
return cls(title, api)发布于 2012-10-25 01:15:40
self是一个普通的局部变量,因此设置self = ..只会更改该函数中的self变量所指向的内容。它不会改变实际的对象。
请参阅:Is it safe to replace a self object by another object of the same type in a method?
要做您想做的事情,您可以使用静态函数作为factory
class Page:
cache = []
""" Return cached object """
@staticmethod
def create(title):
for o in Page.cache:
if o.__searchTerm == title or o.title == title:
return o
return Page(title)
""" Initilize the class and start processing """
def __init__(self, title, api=None):
Page.cache.append(self)
# Other init code
self.__searchTerm = title
self.title = title
a = Page.create('test')
b = Page.create('test')
print a.title
print b.titlehttps://stackoverflow.com/questions/13054250
复制相似问题