Thuộc tính trong Python là gì?
Nếu chúng ta đã từng làm việc với các ngôn ngữ mô hình OOPS, chúng ta hẳn đã nghe thấy từ "thuộc tính" khá thường xuyên. Có hai loại thuộc tính-lớp thuộc tính và thuộc tính thể hiện. Hướng dẫn này giải thích thuộc tính là gì và loại của chúng, cùng với các ví dụ Show
Vì Python là một công cụ hỗ trợ rất lớn cho mô hình OOPS, nên mọi thứ đều được coi là một đối tượng. Chúng tôi tạo các lớp và đối tượng. Trước khi hiểu thuộc tính, hiểu lớp và đối tượng là nền tảng. Nói một cách đơn giản, một lớp giống như một bản thiết kế và để sử dụng bản thiết kế đó, chúng ta tạo các đối tượng cho lớp đó Ví dụ đầu ra Delhi public school School: Delhi public school Place: Delhi grade: 5 Delhi public school School: Delhi public school Place: Delhi grade: 5 hiểu biết Trong ví dụ trên, chúng tôi đã tạo một lớp gọi là "sinh viên" với ba biến và một hàm in các giá trị của ba biến. Mọi đối tượng chúng ta tạo cho lớp đều có quyền truy cập vào các biến trong lớp. Các biến này được gọi là "Thuộc tính" và các hàm được gọi là phương thức (còn được gọi là hàm). Trong chương trình trên, chúng ta đã tạo hai đối tượng của lớp, s1 và s2, đồng thời truy cập thuộc tính sch_name và phương thức display() in giá trị của các thuộc tính Các loại thuộc tínhThuộc tính lớp
Ví dụ đầu ra Student1: Ryan Harvard Cambridge Massachusetts Boston United States Student2: Tony Harvard Cambridge Massachusetts Boston United States
Thuộc tính sơ thẩm
Ví dụ đầu ra Student1: Ryan 18 NYU Student1: Roy 18 Duke
Khi chúng ta tạo student1 Khi chúng tôi tạo student2 Cả thuộc tính Instance và thuộc tính Lớp đều đóng vai trò nổi bật trong việc tạo lớp âm thanh. Đây là một ví dụ sử dụng cả biến lớp và biến thể hiện để tạo một lớp Thuộc tính lớp Python so với Java. Lập trình hướng đối tượng Đánh dấu là đã hoàn thành Vật liệu hỗ trợCác slide khóa học hướng dẫn được đề xuất (. pdf) Mã mẫu (. nén)
Trở thành Thành viên để tham gia cuộc trò chuyện Trong một màn hình điện thoại gần đây, tôi đã quyết định sử dụng một thuộc tính lớp để triển khai một API Python nhất định. Người phỏng vấn của tôi đã thách thức tôi, đặt câu hỏi liệu mã của tôi có hợp lệ về mặt cú pháp hay không, khi nó được thực thi, v.v. Trên thực tế, bản thân tôi cũng không chắc chắn về câu trả lời. Vì vậy, tôi đã làm một số đào. Thuộc tính lớp Python. khi nào (hoặc làm thế nào) sử dụng chúng. Trong hướng dẫn này, tôi sẽ hướng dẫn bạn những cạm bẫy phổ biến và kết luận bằng một danh sách các trường hợp sử dụng hợp lệ có thể giúp bạn tiết kiệm thời gian, năng lượng và dòng mã Chia sẻ Chia sẻTrong một màn hình điện thoại gần đây, tôi đã quyết định sử dụng một thuộc tính lớp để triển khai một API Python nhất định. Người phỏng vấn của tôi đã thách thức tôi, đặt câu hỏi liệu mã của tôi có hợp lệ về mặt cú pháp hay không, khi nó được thực thi, v.v. Trên thực tế, bản thân tôi cũng không chắc chắn về câu trả lời. Vì vậy, tôi đã làm một số đào. Thuộc tính lớp Python. khi nào (hoặc làm thế nào) sử dụng chúng. Trong hướng dẫn này, tôi sẽ hướng dẫn bạn những cạm bẫy phổ biến và kết luận bằng một danh sách các trường hợp sử dụng hợp lệ có thể giúp bạn tiết kiệm thời gian, năng lượng và dòng mã Tác giả Charles MarshCharles đã từng là trưởng nhóm kỹ thuật tại Khan Academy, Cedar và Spring Discovery Ghi chú của biên tập viên. Bài viết này đã được cập nhật vào ngày 29/11/22 bởi nhóm biên tập của chúng tôi. Nó đã được sửa đổi để bao gồm các nguồn gần đây và phù hợp với các tiêu chuẩn biên tập hiện tại của chúng tôi Gần đây tôi đã có một màn hình điện thoại phỏng vấn lập trình, trong đó chúng tôi đã sử dụng một trình soạn thảo văn bản hợp tác và điều đó khiến tôi suy nghĩ về các thuộc tính của lớp Python Tôi được yêu cầu triển khai một API nhất định và đã chọn thực hiện bằng Python. Trừu tượng hóa câu lệnh vấn đề, giả sử tôi cần một lớp có các thể hiện được lưu trữ một số 3 và một số 4Tôi hít một hơi thật sâu và bắt đầu gõ. Sau một vài dòng, tôi đã có một cái gì đó như thế này
Người phỏng vấn của tôi đã ngăn tôi lại
Để tham khảo và cung cấp cho bạn ý tưởng về mục đích của tôi, đây là cách tôi sửa đổi mã
Hóa ra, cả hai chúng ta đều sai. Câu trả lời thực sự nằm ở việc hiểu được sự khác biệt giữa các thuộc tính lớp Python và các thuộc tính thể hiện của Python Ghi chú. Nếu bạn là một chuyên gia xử lý các thuộc tính lớp Python, bạn có thể bỏ qua để chuyển sang các trường hợp sử dụng Thuộc tính lớp PythonNgười phỏng vấn của tôi đã sai ở chỗ đoạn mã trên hợp lệ về mặt cú pháp Tôi đã sai ở chỗ mã không đặt "giá trị mặc định" cho thuộc tính thể hiện. Thay vào đó, nó định nghĩa 3 như một thuộc tính lớp có giá trị 7Theo kinh nghiệm của tôi, các thuộc tính lớp Python là một chủ đề mà nhiều người biết điều gì đó, nhưng ít người hiểu hoàn toàn Biến lớp Python so với. Biến thể hiện. Có gì khác biệt?Thuộc tính lớp Python là thuộc tính của lớp (thông tư, tôi biết), chứ không phải là thuộc tính của một thể hiện của lớp Hãy sử dụng một ví dụ lớp Python để minh họa sự khác biệt. Ở đây, 8 là thuộc tính lớp và 9 là thuộc tính thể hiện
Lưu ý rằng tất cả các phiên bản của lớp đều có quyền truy cập vào 8 và nó cũng có thể được truy cập như một thuộc tính của chính lớp đó
Đối với các lập trình viên Java hoặc C++, thuộc tính lớp tương tự—nhưng không giống hệt—với thành viên tĩnh. Chúng ta sẽ thấy chúng khác nhau như thế nào sau Thuộc tính lớp Python so với. Không gian tên đối tượngĐể hiểu những gì đang xảy ra ở đây, hãy nói ngắn gọn về không gian tên Python Không gian tên là ánh xạ từ tên đến đối tượng, với thuộc tính không có mối quan hệ nào giữa các tên trong các không gian tên khác nhau. Chúng thường được triển khai dưới dạng từ điển Python, mặc dù điều này được trừu tượng hóa Tùy thuộc vào ngữ cảnh, bạn có thể cần truy cập một không gian tên bằng cách sử dụng cú pháp dấu chấm (e. g. , 1) hoặc dưới dạng biến cục bộ (e. g. , 2). Như một ví dụ cụ thể
Các lớp Python và các thể hiện của các lớp đều có các không gian tên riêng biệt được đại diện bởi 3 và 4, tương ứngKhi bạn cố gắng truy cập các thuộc tính Python từ một thể hiện của một lớp, trước tiên nó sẽ xem không gian tên thể hiện của nó. Nếu nó tìm thấy thuộc tính, nó sẽ trả về giá trị được liên kết. Nếu không, nó sẽ tìm trong không gian tên của lớp và trả về thuộc tính (nếu có, nếu không sẽ báo lỗi). Ví dụ
Không gian tên cá thể được ưu tiên hơn không gian tên lớp. Nếu có một thuộc tính Python có cùng tên trong cả hai, không gian tên đối tượng sẽ được kiểm tra trước và giá trị của nó được trả về. Đây là một tra cứu thuộc tính for
Và, ở dạng trực quan Cách thuộc tính lớp Python xử lý chuyển nhượngVới suy nghĩ này, chúng ta có thể hiểu được cách các thuộc tính của lớp xử lý việc gán
Ở cấp độ không gian tên, chúng tôi đang đặt 5. (Ghi chú. Đây không phải là mã chính xác mà sẽ là 6 vì 7 trả về một , một trình bao bọc bất biến để ngăn việc gán trực tiếp, nhưng nó giúp ích cho mục đích trình diễn). Sau đó, khi chúng tôi truy cập 8, 8 có một giá trị mới trong không gian tên lớp và do đó 2 được trả về
Ở cấp độ không gian tên, chúng tôi đang thêm thuộc tính 8 vào 1, vì vậy khi tra cứu 8, chúng tôi trả về 2. Trong khi đó, các phiên bản khác của 3 sẽ không có 8 trong không gian tên phiên bản của chúng, vì vậy chúng tiếp tục tìm thấy 8 trong 3 và do đó trả về 1khả năng biến đổiNếu thuộc tính lớp của bạn có loại có thể thay đổi thì sao? Hãy quay lại 7 mà tôi đã xác định trước đó và xem việc sử dụng biến lớp của tôi có thể dẫn đến các vấn đề sau này như thế nào
Mục tiêu của tôi là có danh sách trống (_______3_______7) làm giá trị mặc định cho 3 và đối với mỗi trường hợp của 7 để có dữ liệu riêng sẽ được thay đổi theo thời gian trên cơ sở từng trường hợp. Nhưng trong trường hợp này, chúng tôi có hành vi sau (lưu ý rằng 4 là tùy ý trong ví dụ này) 0Điều này là không tốt—việc thay đổi biến lớp Python của chúng ta thông qua một phiên bản sẽ thay đổi nó cho tất cả các phiên bản khác Ở cấp độ không gian tên, tất cả các phiên bản của 7 đang truy cập và sửa đổi cùng một danh sách trong 3 mà không tạo các thuộc tính 3 của riêng chúng trong không gian tên của phiên bản của chúngChúng ta có thể giải quyết vấn đề này bằng cách sử dụng bài tập; 1Trong trường hợp này, chúng tôi đang thêm 6, vì vậy 7 ban đầu không thay đổiThật không may, điều này đòi hỏi người dùng 7 phải có kiến thức sâu sắc về các biến của nó và cách giải quyết này chắc chắn dễ mắc lỗi. Theo một nghĩa nào đó, chúng tôi sẽ giải quyết các triệu chứng hơn là nguyên nhân. Tốt hơn là có một cái gì đó chính xác bằng cách xây dựngGiải pháp cá nhân của tôi. Nếu bạn chỉ đang sử dụng một biến lớp để gán một giá trị mặc định cho một biến thể hiện của Python, thì đừng sử dụng các giá trị có thể thay đổi. Trong trường hợp này, mọi phiên bản của 7 cuối cùng sẽ ghi đè lên 0 bằng thuộc tính phiên bản riêng của nó, do đó, việc sử dụng một danh sách trống làm mặc định dẫn đến một lỗi nhỏ dễ bị bỏ qua. Thay vì ở trên, chúng ta có thể có một trong hai
Ví dụ 2Tất nhiên, chúng tôi phải xử lý trường hợp 1 một cách thích hợp, nhưng đó là một cái giá nhỏ phải trảKhi nào bạn nên sử dụng thuộc tính lớp Python?Các thuộc tính của lớp rất phức tạp, nhưng hãy xem xét một số trường hợp chúng sẽ hữu ích
Có liên quan. Mẹo và phương pháp hay nhất về Python của Toptal Developers Dưới mui xeGhi chú. Nếu bạn lo lắng về hiệu suất ở cấp độ này, thì bạn có thể không muốn sử dụng Python ngay từ đầu, vì sự khác biệt sẽ ở mức phần mười mili giây—nhưng vẫn thú vị khi tìm hiểu một chút và điều đó sẽ hữu ích Nhớ lại rằng không gian tên của một lớp được tạo và điền vào thời điểm định nghĩa lớp. Điều đó có nghĩa là chúng ta chỉ thực hiện một phép gán cho một biến lớp nhất định, trong khi các biến thể hiện phải được gán mỗi khi một thể hiện mới được tạo Hãy lấy một ví dụ 8Chúng tôi chỉ giao cho 8 một lần, nhưng 9 trong mọi cuộc gọi tới 0Để có thêm bằng chứng, hãy sử dụng trình dịch ngược Python 9Khi chúng ta nhìn vào mã byte, một lần nữa rõ ràng là 1 phải thực hiện hai nhiệm vụ, trong khi 2 chỉ thực hiện một nhiệm vụTrong thực tế, mức tăng này thực sự trông như thế nào? Tuy nhiên, tôi nghĩ rằng những đoạn mã nhỏ này (chạy với mô-đun timeit của Python) giúp minh họa sự khác biệt giữa các biến lớp và biến thể hiện, vì vậy tôi vẫn đưa chúng vào Ghi chú. Tôi đang dùng MacBook Pro với OS X 10. 8. 5 và Trăn 2. 7. 2 Khởi tạo 0Việc khởi tạo của 3 nhanh hơn hơn một giây, do đó, sự khác biệt ở đây dường như có ý nghĩa thống kêVậy tại sao lại như vậy? . Chúng tôi làm hai bài tập trong 1, nhưng chỉ một bài trong 2Phân công 1Ghi chú. Không có cách nào để chạy lại mã thiết lập của bạn trong mỗi lần dùng thử theo thời gian, vì vậy chúng tôi phải khởi tạo lại biến của mình trong lần dùng thử. Dòng thời gian thứ hai biểu thị thời gian trên với thời gian khởi tạo được tính toán trước đó đã trừ Từ những điều trên, có vẻ như 6 chỉ mất khoảng 60% miễn là 3 để xử lý các bài tậpTại sao điều này là trường hợp? . Khi chúng tôi gán cho 8, trước tiên chúng tôi tìm trong vùng tên cá thể ( 9), không tìm thấy 0, sau đó tìm trong vùng tên lớp ( 1), sau đó thực hiện phép gán thích hợp. Khi chúng tôi gán cho 2, chúng tôi thực hiện số lần tra cứu bằng một nửa so với khi chúng tôi gán ngay cho không gian tên thực thể ( 3)Tóm lại, mặc dù những mức tăng hiệu suất này không quan trọng trong thực tế, nhưng những thử nghiệm này rất thú vị ở cấp độ khái niệm. Nếu có bất cứ điều gì, tôi hy vọng những khác biệt này sẽ giúp minh họa sự khác biệt cơ học giữa các biến lớp và biến thể hiện Tóm lại làCác thuộc tính lớp dường như không được sử dụng đúng mức trong Python; của tôi. Các biến lớp Python có vị trí của chúng trong trường mã tốt. Khi được sử dụng cẩn thận, chúng có thể đơn giản hóa mọi thứ và cải thiện khả năng đọc. Nhưng khi bất cẩn ném vào một lớp nhất định, họ chắc chắn sẽ làm bạn vấp ngã ruột thừa. Biến thể hiện cá nhânMột biến bổ sung cần đề cập. biến thể hiện riêng tư Có thể nói, Python không có các biến riêng tư, nhưng một mối quan hệ thú vị khác giữa cách đặt tên lớp và cá thể đi kèm với việc xáo trộn tên Trong hướng dẫn về phong cách Python, người ta nói rằng các biến giả riêng phải được thêm tiền tố bằng dấu gạch dưới kép. '__'. Đây không chỉ là một dấu hiệu cho những người khác biết rằng biến của bạn được xử lý riêng tư mà còn là một cách để ngăn chặn quyền truy cập vào nó. Đây là những gì tôi muốn nói 2Nhìn kìa. Thuộc tính thể hiện 4 được tự động thêm tiền tố vào tên lớp để tạo ra 5Mặc dù vẫn có thể giải quyết và có thể lấy được bằng cách sử dụng 6, nhưng việc xáo trộn tên này là một phương tiện để tạo một biến “riêng tư” vì nó ngăn cản bạn và những người khác truy cập vào nó một cách tình cờ hoặc do thiếu hiểu biếtBiên tập. Như Pedro Werneck đã chỉ ra, hành vi này chủ yếu nhằm giúp phân lớp. Trong , họ thấy nó phục vụ hai mục đích. (1) ngăn các lớp con truy cập các thuộc tính nhất định và (2) ngăn xung đột không gian tên trong các lớp con này. Mặc dù hữu ích, nhưng việc xáo trộn biến không nên được coi là lời mời viết mã với sự phân biệt công khai-riêng tư giả định, chẳng hạn như có trong Java Đọc thêm trên Blog Kỹ thuật Toptal
Không gian tên Python là ánh xạ từ tên đến đối tượng, với thuộc tính không có mối quan hệ nào giữa các tên trong các không gian tên khác nhau. Không gian tên thường được triển khai dưới dạng từ điển Python, mặc dù điều này được trừu tượng hóa Trong Python, một phương thức lớp là một phương thức được gọi với lớp làm ngữ cảnh. Đây thường được gọi là phương thức tĩnh trong các ngôn ngữ lập trình khác. Mặt khác, một phương thức thể hiện được gọi với một thể hiện là bối cảnh Trong trường hợp đó, không gian tên cá thể được ưu tiên hơn không gian tên lớp. Nếu có một thuộc tính có cùng tên trong cả hai, không gian tên đối tượng sẽ được kiểm tra trước và giá trị của nó được trả về |