2009-09-11 14 views
16

Đây là lỗi tôi nhận được hôm nay tại http://filmaster.com "> filmaster.com:PicklingError: Không thể chọn <class 'decimal.Decimal'>: nó không phải là cùng một đối tượng như decimal.Decimal

PicklingError: Can't pickle : it's not the same object as decimal.Decimal

gì mà chính xác có nghĩa là Nó dường như không thể làm cho rất nhiều ý nghĩa ... dường như được kết nối với bộ nhớ đệm django Bạn có thể xem toàn bộ traceback đây:?.

Traceback (most recent call last):

File "/home/filmaster/django-trunk/django/core/handlers/base.py", line 92, in get_response response = callback(request, *callback_args, **callback_kwargs)

File "/home/filmaster/film20/film20/core/film_views.py", line 193, in show_film
workflow.set_data_for_authenticated_user()

File "/home/filmaster/film20/film20/core/film_views.py", line 518, in set_data_for_authenticated_user
object_id = self.the_film.parent.id)

File "/home/filmaster/film20/film20/core/film_helper.py", line 179, in get_others_ratings
set_cache(CACHE_OTHERS_RATINGS, str(object_id) + "_" + str(user_id), userratings)

File "/home/filmaster/film20/film20/utils/cache_helper.py", line 80, in set_cache return cache.set(CACHE_MIDDLEWARE_KEY_PREFIX + full_path, result, get_time(cache_string))

File "/home/filmaster/django-trunk/django/core/cache/backends/memcached.py", line 37, in set
self._cache.set(smart_str(key), value, timeout or self.default_timeout)

File "/usr/lib/python2.5/site-packages/cmemcache.py", line 128, in set val, flags = self._convert(val)

File "/usr/lib/python2.5/site-packages/cmemcache.py", line 112, in _convert val = pickle.dumps(val, 2)

PicklingError: Can't pickle : it's not the same object as decimal.Decimal

Và mã nguồn cho Filmaster có thể được tải xuống từ đây: bitbucket.org/filmaster/filmaster-test

Mọi trợ giúp sẽ được đánh giá cao.

+0

Tôi đã nhận được một lỗi tương tự sau khi viết một phương pháp __getstate__ sai cho một đối tượng thay đổi hành vi dưa của nó. Bạn không chắc chắn vấn đề là gì nhưng hãy kiểm tra xem có vấn đề gì không. – partofthething

+0

Tôi cũng thấy điều này với trang trí lớp, cụ thể là sáu.add_metaclass – dbn

Trả lời

16

Một sự kỳ quặc của Pickle là cách bạn nhập một lớp trước khi bạn chọn một trong các trường hợp của nó có thể thay đổi một cách tinh tế đối tượng được chọn. Pickle yêu cầu bạn phải nhập khẩu đối tượng giống hệt nhau trước khi bạn chọn nó và trước khi bạn tháo nó ra.

Vì vậy, ví dụ:

from a.b import c 
C = c() 
pickler.dump(C) 

sẽ làm cho một đối tượng tinh tế khác nhau (đôi khi) tới:

from a import b 
C = b.c() 
pickler.dump(C) 

Hãy thử không quan trọng với hàng nhập khẩu của bạn, nó có thể khắc phục sự cố.

+8

vậy làm thế nào đến vấn đề tẩy này chỉ xảy ra một lần trong hàng ngàn yêu cầu và bình thường nó hoạt động tốt? – michuk

2

Bạn đã từng bằng cách nào đó reload(decimal) hoặc monkeypatch mô-đun thập phân để thay đổi lớp Thập phân? Đây là hai điều có khả năng nhất để tạo ra một vấn đề như vậy.

+0

Không, không có gì trên loại đó. Tôi chỉ nhập lớp Thập phân. – michuk

17

Tôi gặp lỗi này khi chạy trong sổ ghi chú jupyter. Tôi nghĩ rằng vấn đề là tôi đang sử dụng %load_ext autoreloadautoreload 2. Khởi động lại kernel và rerunning của tôi đã giải quyết được vấn đề.

+0

Có vẻ như việc thay đổi một phương thức lớp học là nguyên nhân của vấn đề. Tôi đoán là 'autoreload' không cập nhật định nghĩa được lưu ở một nơi khác. Khởi động lại sẽ khắc phục nó vì định nghĩa mới hơn được tải ở cả hai vị trí. – theindigamer

2

Có thể có sự cố khi bắt đầu quá trình với multiprocessing bằng cách gọi __init__. Dưới đây là một bản demo:

import multiprocessing as mp 

class SubProcClass: 
    def __init__(self, pipe, startloop=False): 
     self.pipe = pipe 
     if startloop: 
      self.do_loop() 

    def do_loop(self): 
     while True: 
      req = self.pipe.recv() 
      self.pipe.send(req * req) 

class ProcessInitTest: 
    def __init__(self, spawn=False): 
     if spawn: 
      mp.set_start_method('spawn') 
     (self.msg_pipe_child, self.msg_pipe_parent) = mp.Pipe(duplex=True) 

    def start_process(self): 
     subproc = SubProcClass(self.msg_pipe_child) 
     self.trig_proc = mp.Process(target=subproc.do_loop, args=()) 
     self.trig_proc.daemon = True 
     self.trig_proc.start() 

    def start_process_fail(self): 
     self.trig_proc = mp.Process(target=SubProcClass.__init__, args=(self.msg_pipe_child,)) 
     self.trig_proc.daemon = True 
     self.trig_proc.start() 

    def do_square(self, num): 
     # Note: this is an synchronous usage of mp, 
     # which doesn't make sense. But this is just for demo 
     self.msg_pipe_parent.send(num) 
     msg = self.msg_pipe_parent.recv() 
     print('{}^2 = {}'.format(num, msg)) 

Bây giờ, với đoạn mã trên, nếu chúng ta chạy này:

if __name__ == '__main__': 
    t = ProcessInitTest(spawn=True) 
    t.start_process_fail() 
    for i in range(1000): 
     t.do_square(i) 

Chúng tôi nhận được lỗi này:

Traceback (most recent call last): 
    File "start_class_process1.py", line 40, in <module> 
    t.start_process_fail() 
    File "start_class_process1.py", line 29, in start_process_fail 
    self.trig_proc.start() 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/process.py", line 105, in start 
    self._popen = self._Popen(self) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/context.py", line 212, in _Popen 
    return _default_context.get_context().Process._Popen(process_obj) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/context.py", line 274, in _Popen 
    return Popen(process_obj) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/popen_spawn_posix.py", line 33, in __init__ 
    super().__init__(process_obj) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/popen_fork.py", line 21, in __init__ 
    self._launch(process_obj) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/popen_spawn_posix.py", line 48, in _launch 
    reduction.dump(process_obj, fp) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/reduction.py", line 59, in dump 
    ForkingPickler(file, protocol).dump(obj) 
_pickle.PicklingError: Can't pickle <function SubProcClass.__init__ at 0x10073e510>: it's not the same object as __main__.__init__ 

Và nếu chúng ta thay đổi nó để sử dụng fork thay vì spawn:

if __name__ == '__main__': 
    t = ProcessInitTest(spawn=False) 
    t.start_process_fail() 
    for i in range(1000): 
     t.do_square(i) 

Chúng tôi nhận được lỗi này:

Process Process-1: 
Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap 
    self.run() 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/process.py", line 93, in run 
    self._target(*self._args, **self._kwargs) 
TypeError: __init__() missing 1 required positional argument: 'pipe' 

Nhưng nếu chúng ta gọi phương thức start_process, mà không gọi __init__ trong mục tiêu mp.Process, như thế này:

if __name__ == '__main__': 
    t = ProcessInitTest(spawn=False) 
    t.start_process() 
    for i in range(1000): 
     t.do_square(i) 

Nó hoạt động như mong đợi (cho dù chúng tôi sử dụng spawn hoặc fork).

0

Tôi không thể giải thích tại sao điều này là không một trong hai, nhưng giải pháp của riêng tôi để khắc phục điều này đã thay đổi tất cả các mã của tôi từ làm

from point import Point 

để

import point 

một sự thay đổi này và nó đã làm việc. Tôi rất muốn biết tại sao ... hth

Các vấn đề liên quan