Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
561 views
in Technique[技术] by (71.8m points)

caching - Python object cache

I tried a bit of code but it seems to cause issues:

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)

Then I try:

a = Page('test')
b = Page('test')

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

Whats wrong with this bit of code? Why wont it work? Is there a way to make it work? If not how do I go about easily and transparently to the end user caching objects?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

if you want to manipulate the creation, you need to change __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
>>> 

EDIT: using __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
>>> 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...