Tôi vừa mới chiến đấu với một lỗi trong Python. Đó là một trong những lỗi newbie ngớ ngẩn, nhưng nó đã cho tôi suy nghĩ về các cơ chế của Python (Tôi là một lập trình viên C++ thời gian dài, mới với Python). Tôi sẽ đặt ra mã lỗi và giải thích những gì tôi đã làm để sửa chữa nó, và sau đó tôi có một vài câu hỏi ...Thành viên lớp học Python Khởi tạo
Kịch bản: Tôi có một lớp, có thành viên dữ liệu từ điển, sau đây là mã của nó (đây là đơn giản hóa tất nhiên):
class A:
dict1={}
def add_stuff_to_1(self, k, v):
self.dict1[k]=v
def print_stuff(self):
print(self.dict1)
lớp sử dụng mã này là lớp B:
class B:
def do_something_with_a1(self):
a_instance = A()
a_instance.print_stuff()
a_instance.add_stuff_to_1('a', 1)
a_instance.add_stuff_to_1('b', 2)
a_instance.print_stuff()
def do_something_with_a2(self):
a_instance = A()
a_instance.print_stuff()
a_instance.add_stuff_to_1('c', 1)
a_instance.add_stuff_to_1('d', 2)
a_instance.print_stuff()
def do_something_with_a3(self):
a_instance = A()
a_instance.print_stuff()
a_instance.add_stuff_to_1('e', 1)
a_instance.add_stuff_to_1('f', 2)
a_instance.print_stuff()
def __init__(self):
self.do_something_with_a1()
print("---")
self.do_something_with_a2()
print("---")
self.do_something_with_a3()
Chú ý rằng tất cả các cuộc gọi đến do_something_with_aX()
khởi một "sạch" mới thể hiện của lớp A, và in từ điển trước và sau khi thêm vào.
Các lỗi (nếu bạn chưa hình dung nó ra chưa):
>>> b_instance = B()
{}
{'a': 1, 'b': 2}
---
{'a': 1, 'b': 2}
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
---
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
{'a': 1, 'c': 1, 'b': 2, 'e': 1, 'd': 2, 'f': 2}
Trong khởi thứ hai của lớp A, từ điển không có sản phẩm nào, nhưng bắt đầu với những nội dung của việc khởi tạo trước, và kể từ đó trở đi. Tôi mong họ bắt đầu "tươi".
gì giải quyết này "lỗi" được rõ ràng thêm:
self.dict1 = {}
Trong __init__
constructor của lớp A. Tuy nhiên, điều đó khiến tôi ngạc nhiên:
- ý nghĩa của "dict1 là gì = {} "khởi tạo tại điểm khai báo của dict1 (dòng đầu tiên trong lớp A)? Nó là vô nghĩa?
- Cơ chế khởi tạo là nguyên nhân sao chép tham chiếu từ lần khởi chạy cuối cùng?
- Nếu tôi thêm "self.dict1 = {}" vào hàm tạo (hoặc bất kỳ thành viên dữ liệu nào khác), nó không ảnh hưởng như thế nào đến thành viên từ điển của các phiên bản khởi tạo trước đó?
EDIT: Sau câu trả lời bây giờ tôi hiểu rằng bằng cách tuyên bố một thành viên dữ liệu và không đề cập đến nó trong __init__
hoặc ở một nơi khác như self.dict1, tôi hầu như xác định những gì được gọi là trong C++/Java một thành viên dữ liệu tĩnh. Bằng cách gọi nó self.dict1 tôi đang làm cho nó "dụ ràng buộc".
Bạn nên sử dụng các lớp kiểu mới, lấy được từ đối tượng. – nikow