2012-02-26 100 views
0

我創建了Django File對象的子類來照顧遠程文件。 我也想通過創建一個RemoteFileLazy子類化Lazyobject類來創建一個懶惰版本,但它不能像我期望的那樣工作。我收到一個錯誤。RuntimeError:超過最大遞歸深度:爲什麼?

import urllib2 
from django.core.files.base import File 
from django.utils.functional import LazyObject 

class RemoteFile(File): 

    def __init__(self, url): 
     super(RemoteFile, self).__init__(urllib2.urlopen(urllib2.Request(url))) 

    def __str__(self): 
     return 'Remote content' 

    def __nonzero__(self): 
     return True 

    def open(self, mode=None): 
     self.seek(0) 

    def close(self): 
     pass 

    def chunks(self, chunk_size=None): 
    # CHUNKS taking care of no known size! 
     if not chunk_size: 
      chunk_size = self.DEFAULT_CHUNK_SIZE 

     if hasattr(self, 'seek'): 
      self.seek(0) 
     # Assume the pointer is at zero... 
     counter = self.size 

     while True: 
      data = self.read(chunk_size) 
      if not data: 
       break 
      yield data 

class RemoteFileLazy(LazyObject): 

    def __init__(self, url): 
     # # as said in the django code: For some reason, we have to inline LazyObject.__init__ here to avoid 
     # recursion 
     self._wrapped = None 
     self.url = url 

    def _setup(self): 
     self._wrapped = RemoteFile(self.url) 

當我運行這段代碼:

rfl = filehelper.RemoteFileLazy(url="http://www.google.fr") 

我得到這個錯誤:

RuntimeError: maximum recursion depth exceeded 

任何想法?我沒有叫LazyObject。 init因爲它在django代碼中提到,雖然... 我認爲init方法中的「self.url = url」會觸發這個錯誤嗎?所以我不能使用具有屬性的懶惰對象?

謝謝。

回溯:

c:\Users\Michael\Dropbox\development\tools\Portable Python 2.7.2.1-django1.3.1\App\lib\site-packages\django\utils\functional.pyc in __getattr__(self, name) 
    274  def __getattr__(self, name): 
    275   if self._wrapped is None: 
--> 276    self._setup() 
    277   return getattr(self._wrapped, name) 
    278 

C:\Users\Michael\Dropbox\development\projects\django-socialdealing\socialdealing\apps\etl\utils\filehelper.py in _setup(self) 
    58 
    59  def _setup(self): 
---> 60   self._wrapped = RemoteFile(self.url) 
    61 
    62 

c:\Users\Michael\Dropbox\development\tools\Portable Python 2.7.2.1-django1.3.1\App\lib\site-packages\django\utils\functional.pyc in __getattr__(self, name) 
    274  def __getattr__(self, name): 
    275   if self._wrapped is None: 
--> 276    self._setup() 
    277   return getattr(self._wrapped, name) 
    278 
+1

你可以粘貼一部分追蹤,以便我們可以看到什麼函數被無限遞歸? – 2012-02-26 23:21:00

+0

當然,我補充一下。 – Michael 2012-02-26 23:33:07

回答

1

你不能在正常的方式LazyObject包裝分配屬性,它的意圖被視爲它是被包裝的對象,所以試圖通過訪問,通過對包裝對象,該對象尚未在您分配給url的位置創建。

爲了解決這個問題,更換

self.url = url # this tries to retrieve the wrapped object to set its 'url' attribute 

self.__dict__['url'] = url # this actually stores an attribute on the LazyObject container. 

順便說一句,當「借」的Django這樣的內部,你會希望每一次升級Django的時間來測試真的硬。

相關問題