5

Trong mô-đun a.pyphương pháp mô-đun Gán cho một biến lớp hoặc Instance biến

def task(): 
    print "task called" 

a = task 

class A: 

    func = task    # this show error unbound method 
    #func = task.__call__ # if i replace with this work 

    def __init__(self): 
     self.func_1 = task 

    def test_1(self): 
     self.func_1() 

    @classmethod 
    def test(cls): 
     cls.func() 


a() 
A().test_1() 
A.test() 

Output:

task called 
task called 
Traceback (most recent call last): 
    File "a.py", line 26, in <module> 
    A.test() 
    File "a.py", line 21, in test 
    cls.func() 
TypeError: unbound method task() must be called with A instance as 
first argument (got nothing instead) 

Trong mô-đun, tôi có thể dễ dàng gán một chức năng để một biến. Khi lớp bên trong cố gắng gán hàm cấp mô-đun cho biến lớp func = task nó hiển thị lỗi, để loại bỏ lỗi này, tôi phải thay thế nó bằng func = task .__ call__ Nhưng khi tôi gán cho ví dụ biến công việc của nó là . func_1 = task.

Câu hỏi của tôi là: tại sao tôi không thể gán hàm cấp mô-đun cho biến lớp học mà không có __call__ và khi chức năng tương tự tôi có thể gán cho biến mẫu đang hoạt động.

+2

Ngoài ra, cần lưu ý rằng điều này biên dịch và hoạt động như mong đợi trong python 3.x (cụ thể là 3.6). – Ori

Trả lời

1

Bởi vì bạn ánh xạ một chức năng như phương pháp ràng buộc của A, vì vậy khi bạn đang gọi cls.func đầu tiên bạn hỏi một cái gì đó tương đương với getattr(cls, 'func') trả về <unbound method A.task> NHƯNG, phương pháp cởi ra điều này cần phải được gọi với lớp như là đối số đầu tiên.

Vì vậy, bởi vì trong trường hợp cụ thể này cls.func có nghĩa là "mang lại cho tôi thuộc tính lớp func của cls" nó không thể có nghĩa là với cùng "phương pháp lớp gọi func" thời gian - Vì vậy, Python không dịch cls.func() bởi func(cls).

Nhưng trong cùng một thời điểm, bởi vì func<unbound method A.task> (ràng buộc với A.task), cần gọi là func(cls) để hoạt động.

Kiểm tra nó với một cái gì đó như:

@classmethod 
def test(cls): 
    print getattr(cls, 'func') # <unbound method A.task> 

Bạn có thể sửa chữa nó với một cái gì đó như:

def task(cls=None): 
    if cls is None: 
     print 'task()' 
    else: 
     print 'A.foo({})'.format(cls) 

a = task 

class A: 
    func = task    # this show error unbound method 

    def __init__(self): 
     self.func_1 = task 

    def test_1(self): 
     self.func_1() 

    @classmethod 
    def test(cls): 
     cls.func(cls()) 

a() 
A().test_1() 
A.test() 

Output:

task() 
task() 
A.foo(<__main__.A instance at 0x7fd0310a46c8>) 

Lưu ý rằng python3 loại bỏ phương pháp ràng buộc, điều này chỉ hoạt động với python2.x

+0

nguồn là gì cho điều này – Kallz

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