首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python对象缓存

Python对象缓存
EN

Stack Overflow用户
提问于 2012-10-25 01:12:23
回答 3查看 11.5K关注 0票数 7

我尝试了一些代码,但似乎导致了问题:

代码语言:javascript
复制
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)

然后我试着:

代码语言:javascript
复制
a = Page('test')
b = Page('test')

print a.title # works
print b.title # AttributeError: Page instance has no attribute 'title'

这段代码有什么问题?为什么它不能工作?有没有办法让它工作呢?如果不是,我该如何轻松、透明地访问最终用户缓存对象呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-25 01:31:02

如果您想要操作创建,则需要更改__new__

代码语言:javascript
复制
>>> 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__

代码语言:javascript
复制
>>> 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
>>> 
票数 9
EN

Stack Overflow用户

发布于 2012-10-25 01:23:00

一旦创建了对象,您就不能真正更改它的实例。当将self设置为其他值时,您所要做的就是更改变量指向的引用,这样实际的对象就不会受到影响。

这也解释了为什么title属性不在那里。一旦更改了本地self变量,就会立即返回,从而阻止当前实例初始化title属性(更不用说此时的self不会指向正确的实例)。

因此,基本上,您不能在初始化期间更改对象(在__init__中),因为此时它已经被创建,并被分配给变量。像a = Page('test')这样的构造函数调用实际上与:

代码语言:javascript
复制
a = Page.__new__('test')
a.__init__('test')

如您所见,首先调用的是__new__类构造函数,而这实际上是负责创建实例的人。因此,您可以重写类的__new__方法来操作对象创建。

但是,通常首选的方法是创建一个简单的工厂方法,如下所示:

代码语言:javascript
复制
@classmethod
def create (cls, title, api = None):
    o = cls.__getCache(title)
    if o:
        return o
    return cls(title, api)
票数 4
EN

Stack Overflow用户

发布于 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

代码语言:javascript
复制
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.title
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13054250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档