我创建了一个Django File对象的子类来处理远程文件。 我还想通过创建一个子类化Lazyobject类的RemoteFileLazy来创建一个懒惰的版本,但它不能像我预期的那样工作。我收到了错误。
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
答案 0 :(得分: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时都非常难以测试 。