2011-10-28 14 views
5

Tôi gặp lỗi khi tôi sử dụng dưa chua không có chi tiết.không gian tên trên trăn trăn

tôi đã viết 3 file chương trình:

  1. cho một lớp học để được ngâm,
  2. cho một lớp học mà sử dụng lớp trong # 1,
  3. unittest cho các lớp học thử nghiệm trong # 2.

và các mã thực như sau tương ứng.

# 1. ClassToPickle.py

import pickle 
class ClassToPickle(object): 
    def __init__(self, x): 
     self.x = x 
if __name__=="__main__": 
    p = ClassToPickle(10) 
    pickle.dump(p, open('10.pickle', 'w')) 

# 2. SomeClass.py

from ClassToPickle import ClassToPickle 
import pickle 

class SomeClass(object): 
    def __init__(self): 
     self.pickle = pickle.load(open("10.pickle", 'r')) 
     self.x = self.pickle.x 
     print self.x 

if __name__ == "__main__": 
    SomeClass() 

# 3. SomeClassTest.py

import unittest 
from SomeClass import SomeClass 
from ClassToPickle import ClassToPickle # REQUIRED_LINE 

class SomeClassTest(unittest.TestCase): 
    def testA(self): 
     sc = SomeClass() 
     self.assertEqual(sc.x, 10) 

def main(): 
    unittest.main() 

if __name__ == "__main__": 
    main() 

Tôi đã chạy chương trình số 1 trước tiên để tạo tệp dưa.
Và sau đó, khi tôi chạy tệp chương trình # 2 một mình (ví dụ: nhập "python SomeClass.py"), nó hoạt động.
Và, khi tôi chạy chương trình # 3 một mình (ví dụ: nhập "python SomeClassTest.py"), nó cũng hoạt động.

Tuy nhiên, khi tôi chạy chương trình # 3 dưới dạng "kiểm tra đơn vị" trong nhật thực + pydev, nó sẽ trả về thông báo lỗi bên dưới.

======================================================================
ERROR: testA (SomeClassTest.SomeClassTest)
----------------------------------------------------------------------
Traceback (most recent call last):
$ File "/home/tmp/pickle_problem/SomeClassTest.py", line 9, in testA
sc = SomeClass()
$ File "/home/tmp/pickle_problem/SomeClass.py", line 8, in init
self.pickle = pickle.load(open("10.pickle", 'r'))
$ File "/usr/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
$ File "/usr/lib/python2.7/pickle.py", line 858, in load
dispatchkey
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
$ File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr(mod, name)
$ AttributeError: 'module' object has no attribute 'ClassToPickle'

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (errors=1)

Và cũng có thể, khi tôi nhận xét ra một dòng nhập khẩu lớp ClassToPickle (dòng 3 trong chương trình # 3 và nhận xét là "REQUIRED_LINE"), Nó không làm việc và trả về một thông báo lỗi được mô tả dưới đây.

E
======================================================================
ERROR: testA (main.SomeClassTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "SomeClassTest.py", line 9, in testA
sc = SomeClass()
File "/home/tmp/pickle_problem/SomeClass.py", line 8, in init
self.pickle = pickle.load(open("10.pickle", 'r'))
File "/usr/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
File "/usr/lib/python2.7/pickle.py", line 858, in load
dispatchkey
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'ClassToPickle'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

Tôi đoán vấn đề là về không gian tên trong python, nhưng tôi không biết điều gì đã xảy ra chính xác và tôi có thể làm gì để giải quyết nó.

Làm cách nào để chạy chương trình "# là chính xác (test eclipse + pydev)" # 3,
và chạy chương trình # 3 trong dòng lệnh mà không có dòng nhập ClassToPickle?
Xin hãy giúp tôi.

+0

Có tệp 'ClassToPickle.py' nào khác có thể tìm thấy thay vì tệp bạn đã hiển thị ở đây không? –

+0

@ThomasK Cảm ơn nhận xét của bạn, nhưng câu trả lời là Không. Chỉ có ba tệp .py hiển thị ở đây nằm trong thư mục và tôi chưa bao giờ tạo tệp có tên 'ClassToPickle.py'. – fbessho

Trả lời

6

Đó vì __main__.ClassToPickle != ClassToPickle.ClassToPickle, nghĩ về nó như thế này:

Khi bạn ngâm cá thể lớp của ClassToPickle trong ClassToPickle.py kịch bản, module dưa sẽ dưa tất cả các tham chiếu đến lớp mà có nghĩa là nó sẽ dưa vào tên module trong đó lớp được xác định và vì bạn đã thực thi tập lệnh ClassToPickle.py điều này có nghĩa là mô-đun sẽ được đặt thành __main__ có nghĩa là mô-đun pickle sẽ chọn __main__.ClassToPickle.

Và khi bạn cố gắng tải trường hợp đã chọn không thành công vì nó không tìm thấy lớp của cá thể là __main__.ClassToPickle và không phải là loại bạn nhập bằng cách sử dụng from ClassToPickle import ClassToPickle vì mới nhất này là ClassToPickle.ClassToPickle.

Khắc phục sẽ tạo một tập lệnh khác sẽ xử lý việc bán phá giá thay vì thực hiện trong ClassToPickle.py ví dụ:

import pickle 

from ClassToPickle import ClassToPickle 

if __name__=="__main__": 
    p = ClassToPickle(10) 
    pickle.dump(p, open('10.pickle', 'w')) 
+0

Cảm ơn bạn đã giải thích! Tất cả đều có ý nghĩa đối với tôi và kịch bản của bạn hoạt động cả trong giao diện điều khiển và nhật thực :) – fbessho

+0

@fbessho: Rất vui khi được :) – mouad