2011-08-18 38 views
7

Vì vậy, tôi biết trong python mọi thứ là một 'đối tượng' có nghĩa là nó có thể được chuyển như một đối số cho một phương thức. Nhưng tôi đang cố gắng hiểu chính xác điều này hoạt động như thế nào. Vì vậy, tôi đã thử ví dụ sau:phương thức python làm đối số

class A: 

    def __init__(self): 
     self.value = 'a' 

    def my_method(self) 
     print self.value 

class B: 

    def __init__(self): 
     self.values = 'b' 

    def my_method(self, method): 
     method() 

a = A() 
b = B() 
b.my_method(a.my_method) 

Bây giờ điều đầu tiên được viết chỉ để xem cách hoạt động của mọi thứ. Tôi biết tôi nên ví dụ kiểm tra nếu đối số của my_method là có thể gọi. Bây giờ câu hỏi của tôi là:

Phương pháp được truyền chính xác ở đây như thế nào? Tôi có nghĩa là đầu ra tôi nhận được là 'a' vì vậy tôi đoán rằng khi một phương pháp đối tượng được thông qua như tham số như vậy là đối tượng thực tế? Trong trường hợp này khi tôi vượt qua a.my_method, ví dụ a cũng được thông qua?

+2

Nếu bạn đang làm việc với Python 2, sử dụng 'lớp A (đối tượng):' thay vì 'lớp A:' để có được "các lớp kiểu mới" nói chung tốt hơn và bạn nên làm việc với cái gì. –

Trả lời

8

Khi bạn truy cập a.my_method Python thấy rằng nó là một thuộc tính của lớp và A.my_method có một phương pháp __get__() nên nó gọi A.my_method.__get__(a), phương pháp tạo ra một đối tượng mới (các 'phương pháp ràng buộc'), trong đó có cả một tham chiếu đến A.my_method và tham chiếu đến số a. Khi bạn gọi phương thức liên kết, nó sẽ chuyển cuộc gọi trở lại phương thức cơ bản.

Điều này xảy ra mỗi khi bạn gọi bất kỳ phương pháp nào cho dù bạn gọi trực tiếp hay như trong mã của bạn, hãy trì hoãn cuộc gọi thực sự cho đến sau này. Bạn có thể tìm thêm mô tả về giao thức mô tả như được biết tại http://docs.python.org/reference/datamodel.html#descriptors

+0

Cảm ơn các đầu vào. Python có thể phức tạp cho đến khi bạn quen với nó: D – Bogdan

4

Phương thức được chuyển đến đây chính xác như thế nào?

Điều này dễ dàng được trả lời: trong Python, mọi thứ đều là đối tượng :) Cũng có chức năng/phương pháp, là các đối tượng hàm cụ thể có thể được chuyển thành tham số.

Trong trường hợp này khi tôi chuyển a.my_method, thể hiện a cũng được chuyển?

Có, trong trường hợp này, ví dụ a cũng được chuyển, mặc dù được nhúng trong đối tượng hàm và không thể truy xuất được. Ngược lại, bạn có thể truyền chính hàm đó và cung cấp nó với một cá thể. Hãy xem xét ví dụ sau:

b = B() 
func = A.my_method # Attention, UPPERCASE A 
func(b) 

này sẽ gọi A lớp phương pháp my_method với một thể hiện của B.

+0

Nói đúng cách A.my_method không phải là chính hàm, mà là đối tượng phương thức * không liên kết *. a.my_method là một đối tượng phương thức * bound *. Bạn có thể lấy một cá thể và hàm ban đầu từ a.my_method nếu bạn thực sự thực sự cần đến (kiểm tra mô-đun), nhưng tôi không thấy lý do để làm điều đó ở đây. –

+0

Tôi đã thử đề xuất của bạn nhưng cách duy nhất nó hoạt động được nếu A.my_method là một phương pháp tĩnh có một đối số obj. Nếu không, nó mong đợi một trường hợp của A. – Bogdan

1

Chức năng là 'đối tượng hạng nhất' bằng Python. Điều đó có nghĩa là một hàm là một đối tượng nhiều như một danh sách hoặc một số nguyên. Khi bạn định nghĩa một hàm, bạn thực sự ràng buộc đối tượng hàm với tên mà bạn sử dụng trong def.

Chức năng có thể được gắn với tên khác hoặc được chuyển thành tham số cho hàm (hoặc được lưu trữ trong danh sách hoặc ...).

nguồn: http://mail.python.org/pipermail/tutor/2005-October/042616.html

1

a.my_method lợi nhuận không chính xác chức năng bạn được định nghĩa trong class A (bạn có thể lấy nó qua A.my_method) nhưng một đối tượng gọi là 'phương pháp ràng buộc', trong đó có cả chức năng ban đầu (hoặc 'phương pháp ràng buộc 'trong Python 2, IIRC) và đối tượng mà từ đó nó được lấy ra (đối số self).

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