2012-06-05 8 views
13

我在我的Django應用程序中收到此錯誤,但它只發生一次或更少,並且調試極其困難。不能pickle <type'function'>:屬性查找__builtin __。函數失敗

Environment: 

Request Method: POST 

Django Version: 1.3.1 
Python Version: 2.6.6 
Installed Applications: 
['django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'fimedlabs', 
'data', 
'djcelery'] 
Installed Middleware: 
('django.middleware.common.CommonMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'fimedlabs.auth.userMiddleWare') 


Traceback: 
File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response 
    178.     response = middleware_method(request, response) 
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/middleware.py" in process_response 
    36.     request.session.save() 
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/db.py" in save 
    57.    session_data = self.encode(self._get_session(no_load=must_create)), 
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py" in encode 
    93.   pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL) 

Exception Type: PicklingError at/
Exception Value: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed 

我試過這個問題的答案:

How to tell for which object attribute pickle fails?

加入自我實際的錯誤,看看是否會在Django的錯誤打印任何東西,也沒有用。

我在哪裏可以打印出這個錯誤提供問題的對象,以便它出現在Django錯誤頁面中?

謝謝! 〜馬特

編輯:我在緩存中儲存的唯一對象,是與代碼一個用戶對象:

編輯
class user(object): 
username = str() 
userid = uuid.UUID(int=0) 

client = models.Client() 
clientid = uuid.UUID(int=0) 
clientname = '' 

data = models.User() 
accesslevel = models.AccessLevel() 

active = False 
client_active = False 
isFimed = False 
isFimedAdmin = False 
isClientAdmin = False 
isFimedManager = False 
mysettingsform = None 
viewingas = False 

menu = [] 

_exists = False 
_authenticated = False 

def __str__(self): 
    return str(self.__dict__.copy()) 

def __getstate__(self): 
    return self.__dict__.copy() 

def __setstate__(self, dict): 
    self.__dict__ = dict 

def __init__(self, username=None): 
    if username: 
     self.initialize(username) 

def initialize(self, username): 
    self.username = username 
    model = models.User.objects.filter(username=username).all() 
    if len(model) == 1: 
     model = model[0] 
     self.data = model 
     self._exists = True 
     self.userid = self.data.id 
     self.active = self.data.active 
     self.isFimed = self.data.isFimed() 
     self.isFimedAdmin = self.data.isFimedAdmin() 
     self.isClientAdmin = self.data.isClientAdmin() 
     self.isFimedManager = self.data.isFimedManager() 
     self.mysettingsform = UserFormSelf(initial={"id":model.id, "username":model.username, "name":model.name, "email":model.email, "phone":model.phone}) 

     self.accesslevel = models.AccessLevel.objects.filter(id=self.data.accesslevel_id)[:1][0].level 
     cli = self.data.client 
     self.client = cli 
     self.clientid = cli.id 
     self.clientname = cli.name 
     if cli.active: 
      self.client_active = True 

     model.lastlogin = datetime.datetime.now() 
     model.save() 

     self.menu = getMenu(self.data) 
    else: 
     self._exists = False 

def authenticate(self, password): 
    self._authenticated = False 
    if (self.active == False or self.client_active == False): 
     return False 
    if self._exists: 
     import hashlib 
     hash = hashlib.md5('%s%s' % (str(password), self.data.pwsalt)).hexdigest() 
     if hash == self.data.pwhash: 
      self._authenticated = True 
      return True 
    return False 

def updateUser(self): 
    self.initialize(models.User.objects.filter(id=self.userid).get().username) 

def mkContext(self): 
    c = Context() 
    c['menu'] = self.menu 
    c['user'] = self 
    c['language'] = language 
    c['colors'] = colors 
    c["isFimed"] = self.isFimed 
    c["isFimedAdmin"] = self.isFimedAdmin 
    c["isClientAdmin"] = self.isClientAdmin 
    c["isFimedManager"] = self.isFimedManager 
    c["mysettingsform"] = self.mysettingsform 
    return c 

:WSGI文件WERKZEUG後:

import django.core.handlers.wsgi 
djangoapplication = django.core.handlers.wsgi.WSGIHandler() 
def application(environ, start_response): 
    if 'SCRIPT_NAME' in environ: 
     del environ['SCRIPT_NAME'] 
    return djangoapplication(environ, start_response) 
# The following lines enable the werkzeug debugger 
import django.views.debug 
def null_technical_500_response(request, exc_type, exc_value, tb): 
    raise exc_type, exc_value, tb 
django.views.debug.technical_500_response = null_technical_500_response 
from werkzeug.debug import DebuggedApplication 
application = DebuggedApplication(application, evalex=True) 

回答

6

從哪裏可以打印出這個錯誤提示問題的對象,以便它出現在Django錯誤頁面中?

簡短的答案 - 無需重新編譯cPickle,你不能。

較長的答案:這是一段代碼,引發異常:如果你看夠近

root $ grep -Hra "attribute lookup" /usr/lib64/ 2>/dev/null | grep -a failed 
/usr/lib64/python2.7/lib-dynload/cPickle.so:H�H���P0H�5zM H�=1��M��H��H�ZM �����H�=�1�H���M��H��H��M �����H�4M H�5~H���H���������H�M H�5tH���H���������H��L H�5�H���qH�����d���H�M H�5NH���SH�����F���H�dM H�5bH���5H�����(���H�=X1��O��H�HC H�5I H�=U1�A��H��L �vH��H��I�������H���RK��H�=.H����J��H�5$H��H��H�D$�G��H�D$H��tH�H��H��H��gH�DL�ttH�qH�5nH�=kH��1��XK��H�5bH��H��I����F��H�5\L��H���F��H��tH�EH��H��H�E��M�������I�$H��H��I�$�t���I�DL���P0�d���f�H�EH��H��H�E�F���H�H���P0�7���@H�|$H��P0�����H�H���P0�����H�H���P0�k�����UH��SH�H�H: H���tH�;: H���H�H���u�H�[��H��M��H��attribute deletion is not supportedunsupported pickle protocol: %dargument must have 'read' and 'readline' attributespickle protocol %d asked for; the highest available protocol is %dargument must have 'write' attributeGlobal and instance pickles are not supported.Attempt to getvalue() a non-list-based picklerUnexpected data in internal listBINSTRING pickle has negative byte countno int where int expected in memoCan't pickle %s: import of module %s failedCan't pickle %s: attribute lookup %s.%s failedCan't pickle %s: it's not the same object as %s.%sCan't pickle %s: extension code %s isn't an integerCan't pickle %s: extension code %ld is out of rangecould not convert string to intLONG pickle has negative byte countcould not convert string to floatBINUNICODE pickle has negative byte countunregistered extension code %ld_inverted_registry[%ld] isn't a 2-tuple of stringsA load persistent id instruction was encountered, 

,有一塊寫着

Can't pickle %s: attribute lookup %s.%s failed 

現在,如果你下載的Python源,您可以輕鬆找到負責在./Modules/cPickle.c的功能static int save_global(Picklerobject *self, PyObject *args, PyObject *name)中提出異常的代碼段:

klass = PyObject_GetAttrString(mod, name_str); 
if (klass == NULL) { 
    cPickle_ErrFormat(PicklingError, 
         "Can't pickle %s: attribute lookup %s.%s " 
         "failed", 
         "OSS", args, module, global_name); 
    goto finally; 
} 

因此,調試此錯誤的最佳方法是以不同的方式格式化字符串(可能提供PyString_AS_STRING((PyStringObject *)name),重新編譯並安裝修改後的Python版本。

是的,我知道這太糟糕了。我自己也有同樣的問題。

+0

謝謝!如果/當它回來時,我一定會試試這個。大概2-3周沒有發生過。我會接受這個,但:)因爲werkeug調試器沒有結束爲我工作。 – MatthewKremer

1

使用如django-extensions來安裝werkzeug調試器。您將能夠與每個堆棧幀進行交互。此時,您可以嘗試在會話字典中清理所有的鍵和值。

+0

好吧,我安裝的Django的擴展和WERKZEUG,然後包裹着我的WSGI文件(見第一後爲我修改了它至)。然而,當werkzeug錯誤發生時,我在它的控制檯中輸入了一些東西,它只是通過AJAX返回相同的500頁,而不是用console命令做某些事情。有任何想法嗎? – MatthewKremer

+0

這通常意味着調試器的東西已經在服務器端被破壞。你能否使用django開發服務器複製錯誤(用'runserver_plus'調用)?那裏可能會更好一些。 – Marcin

+0

有沒有辦法讓它啓動時運行runserver_plus而不是runserver?這幾乎不可能重現,它只是隨機發生(看起來),所以我不能運行該命令,然後嘗試調試它。 – MatthewKremer

1

如果要存儲用戶對象,您可能會受到此問題的影響: https://code.djangoproject.com/ticket/16563

這就是說,你最好的選擇將是剛纔修改Django的源代碼,以線93的在/ usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py發生異常。

只記錄session_dict。在大多數情況下,真正明顯的是什麼是錯的。(事實上​​,如果你的回溯顯示Local Vars,你已經有了這個)

9

在我的情況下(與Django無關),當lambda作爲目標函數傳遞時,這個異常被multiprocessing.Pool.map拋出。創建一個命名函數並通過initargs參數(而不是通過閉包)傳遞所需的上下文數據結構來解決此問題。

總之,觸發異常使用情況是:

import multiprocessing as mp 
context = some_object 
pool = mp.Pool() 
worker_func = lambda x: work(x, context) 
results = pool.map(worker_func, data_list) 
+0

'worker_func = lambda x:work(x,context)'在Python2.7中不起作用,但是'def worker_func(x):return work(x,context)'做。並且應該在**'pool = mp.Pool()'之前放** – WeizhongTu

相關問題