2010-05-28 31 views
9

Tôi muốn chọn phương thức không liên kết trong Python 3.x. Tôi gặp phải lỗi này:Chọn phương pháp không liên kết trong Python 3

>>> class A: 
...  def m(self): 
...   pass 
>>> import pickle 
>>> pickle.dumps(A.m) 
Traceback (most recent call last): 
    File "<pyshell#3>", line 1, in <module> 
    pickle.dumps(A.m) 
    File "C:\Python31\lib\pickle.py", line 1358, in dumps 
    Pickler(f, protocol, fix_imports=fix_imports).dump(obj) 
_pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed 

Có ai có kinh nghiệm với điều này không?


Lưu ý: Trong Python 2.x cũng không thể chọn các phương pháp không ràng buộc theo mặc định; Tôi quản lý để làm điều đó có một cách kỳ lạ tôi không hiểu: Tôi đã viết một giảm với mô-đun copy_reg cho lớp MethodType, trong đó bao gồm cả hai phương pháp ràng buộc và không ràng buộc. Nhưng bộ giảm tốc chỉ giải quyết trường hợp của phương pháp bị ràng buộc, bởi vì nó phụ thuộc vào my_method.im_self. Bí ẩn nó cũng đã gây ra Python 2.x để có thể pickle phương pháp unbound. Điều này không xảy ra trên Python 3.x.

Trả lời

7

này không thể được thực hiện trực tiếp bởi vì trong Python 3 cởi ra loại phương pháp đã biến mất: nó chỉ là một chức năng:

>>> print (type (A.m)) 
<class 'function'> 

chức năng Python không bị ràng buộc vào một lớp học, vì vậy nó không thể cho biết những gì lớp A.m thuộc về chỉ bằng cách nhìn vào kết quả biểu thức.

Tùy thuộc vào những gì chính xác bạn cần, tẩy/unpickling một tuple của (lớp, phương pháp tên) có thể là đủ tốt:

>>> print (pickle.loads (pickle.dumps ((A, 'm')))) 
... (<class '__main__.A'>, 'm') 

Bạn có thể lấy phương pháp (chức năng) từ đây chỉ đơn giản bằng cách sử dụng getattr() :

>>> cls, method = pickle.loads (pickle.dumps ((A, 'm'))) 
>>> print (getattr (cls, method)) 
... <function m at 0xb78878ec> 
+1

Bạn đang nói rằng trên Python 3, được đưa ra phương pháp không liên kết, không có cách nào biết được phương thức đó được xác định ở đâu? –

+4

Có. Hãy thử khai báo hai lớp và gán một phương thức từ một đến một lớp khác ('B.m = A.m'). Sau đó, 'B.m' và' A.m' sẽ bằng nhau (trên thực tế, giống hệt nhau), vì vậy không thể biết liệu bạn đã xem phương thức này trong 'B' hay trong' A'. – doublep

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