2015-05-21 14 views
5

Tôi đang đọc về các lớp trong Python (3.4) và từ những gì tôi hiểu có vẻ như mọi đối tượng mới đều có các cá thể phương thức ràng buộc riêng của nó.Python có thực sự tạo ra tất cả các phương pháp ràng buộc cho mỗi cá thể mới không?

class A: 

    def __init__(self, name): 
     self.name = name 

    def foo(self): 
     print(self.name) 

a = A('One') 
b = A('Two') 

print(a.foo == b.foo) 

Kết quả đầu ra là False.

Điều này có vẻ với tôi như một sự lãng phí bộ nhớ. Tôi nghĩ rằng trong nội bộ a.foob.foo sẽ chỉ bằng cách nào đó trong nội bộ để một chức năng trong bộ nhớ: A.foo nơi self như cá thể lớp sẽ được thông qua.

Tôi giả định này có lẽ không thể được thực hiện dễ dàng bằng ngôn ngữ.

Liệu mỗi trường hợp mới cũng chứa trường hợp mới của phương pháp ràng buộc của nó?

Nếu vậy, điều này không làm ảnh hưởng đến hiệu suất hoặc tạo ra trường hợp để tạo đối tượng mới thận trọng hơn các ngôn ngữ khác mà phương pháp "chia sẻ" giữa các đối tượng như trong Java?

+0

Bạn có thể liên kết đến nội dung bạn đã đọc khiến bạn nghĩ vậy không? –

+0

@SotiriosDelimanolis 'X(). F == X.f' sẽ dẫn đến' False' (trong đó f là phương thức instace). Điều này là đủ để làm cho một người nghĩ như vậy. –

+0

Mỗi phương pháp bị ràng buộc, mặc dù, tham chiếu cùng chức năng cơ bản. Chi phí bộ nhớ cho trình bao bọc là tối thiểu. – chepner

Trả lời

14

Phương pháp bị ràng buộc theo yêu cầu, mỗi lần bạn truy cập một.

Truy cập vào tên của một hàm gọi các descriptor protocol, mà trên các đối tượng hàm trả về một phương pháp ràng buộc.

Một phương pháp ràng buộc là một wrapper mỏng xung quanh một đối tượng chức năng; nó lưu trữ một tham chiếu đến hàm gốc và đối tượng. Khi gọi một đối tượng phương thức, nó lần lượt truyền cuộc gọi đến hàm, với thể hiện được chèn vào như một đối số đầu tiên.

Phương thức không được tạo khi cá thể được tạo, do đó không có bộ nhớ bổ sung nào được yêu cầu trước tiên.

Bạn có thể tái tạo các bước thủ công:

>>> class A: 
...  def __init__(self, name): 
...   self.name = name 
...  def foo(self): 
...   print(self.name) 
... 
>>> a = A('One') 
>>> a.foo 
<bound method A.foo of <__main__.A object at 0x100a27978>> 
>>> a.foo.__self__ 
<__main__.A object at 0x100a27978> 
>>> a.foo.__func__ 
<function A.foo at 0x100a22598> 
>>> A.__dict__['foo'] 
<function A.foo at 0x100a22598> 
>>> A.__dict__['foo'].__get__(a, A) 
<bound method A.foo of <__main__.A object at 0x100a27978>> 
>>> A.__dict__['foo'].__get__(a, A)() 
One 

Nó chỉ là đối tượng phương pháp đó được tái tạo mỗi lần; các chức năng cơ bản vẫn ổn định:

>>> a.foo is a.foo 
False 
>>> b = A('Two') 
>>> b.foo is a.foo 
False 
>>> b.foo.__func__ is a.foo.__func__ 
True 

kiến ​​trúc này cũng làm cho classmethod, staticmethod, và property đối tượng làm việc. Bạn có thể tạo ra các mô tả của riêng bạn, tạo ra một loạt các hành vi liên kết thú vị.

+0

Đó là câu trả lời của bạn ở đây, vì vậy bạn có được đại diện bạn rõ ràng không cần nhiều hơn một trong hai cách; o) – jonrsharpe

+0

@jonrsharpe: hah, nhưng điều này đã được chấp nhận! :-P Tôi đã không đọc lại đầy đủ câu hỏi ở đây; nhìn lại cả câu hỏi và câu trả lời là một bản sao hoàn hảo. Tôi đã có ấn tượng có nhiều điều để giải thích về bài viết khác. –

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