Python cho lớp 10 là gì?

Các lớp cung cấp phương tiện kết hợp dữ liệu và chức năng với nhau. Tạo một lớp mới sẽ tạo ra một loại đối tượng mới, cho phép tạo các thể hiện mới của loại đó. Mỗi thể hiện của lớp có thể có các thuộc tính gắn liền với nó để duy trì trạng thái của nó. Các thể hiện của lớp cũng có thể có các phương thức [được định nghĩa bởi lớp của nó] để sửa đổi trạng thái của nó

So với các ngôn ngữ lập trình khác, cơ chế lớp của Python thêm các lớp với cú pháp và ngữ nghĩa mới tối thiểu. Nó là sự kết hợp của các cơ chế lớp có trong C++ và Modula-3. Các lớp Python cung cấp tất cả các tính năng tiêu chuẩn của Lập trình hướng đối tượng. cơ chế kế thừa lớp cho phép nhiều lớp cơ sở, một lớp dẫn xuất có thể ghi đè bất kỳ phương thức nào của lớp cơ sở hoặc các lớp của nó và một phương thức có thể gọi phương thức của lớp cơ sở có cùng tên. Các đối tượng có thể chứa số lượng và loại dữ liệu tùy ý. Điều này đúng với các mô-đun, các lớp tham gia vào bản chất động của Python. chúng được tạo trong thời gian chạy và có thể được sửa đổi thêm sau khi tạo

Theo thuật ngữ C++, thông thường các thành viên của lớp [bao gồm cả thành viên dữ liệu] là công khai [ngoại trừ xem bên dưới] và tất cả các hàm thành viên là ảo. Như trong Modula-3, không có cách viết tắt nào để tham chiếu các thành viên của đối tượng từ các phương thức của nó. chức năng phương pháp được khai báo với một đối số đầu tiên rõ ràng đại diện cho đối tượng, được cung cấp ngầm bởi cuộc gọi. Như trong Smalltalk, bản thân các lớp là các đối tượng. Điều này cung cấp ngữ nghĩa để nhập và đổi tên. Không giống như C++ và Modula-3, các kiểu dựng sẵn có thể được sử dụng làm lớp cơ sở cho phần mở rộng của người dùng. Ngoài ra, giống như trong C++, hầu hết các toán tử tích hợp sẵn với cú pháp đặc biệt [toán tử số học, chỉ số con, v.v. ] có thể được định nghĩa lại cho các thể hiện của lớp

[Thiếu thuật ngữ được chấp nhận rộng rãi để nói về các lớp, thỉnh thoảng tôi sẽ sử dụng thuật ngữ Smalltalk và C++. Tôi sẽ sử dụng thuật ngữ Modula-3, vì ngữ nghĩa hướng đối tượng của nó gần với ngữ nghĩa của Python hơn C++, nhưng tôi hy vọng rằng ít độc giả đã nghe nói về nó. ]

9. 1. Đôi lời về tên và đối tượng

Các đối tượng có tính riêng biệt và nhiều tên [trong nhiều phạm vi] có thể được liên kết với cùng một đối tượng. Điều này được gọi là bí danh trong các ngôn ngữ khác. Điều này thường không được đánh giá cao trong cái nhìn đầu tiên về Python và có thể được bỏ qua một cách an toàn khi xử lý các loại cơ bản không thay đổi [số, chuỗi, bộ dữ liệu]. Tuy nhiên, bí danh có thể có tác động đáng ngạc nhiên đối với ngữ nghĩa của mã Python liên quan đến các đối tượng có thể thay đổi như danh sách, từ điển và hầu hết các loại khác. Điều này thường được sử dụng vì lợi ích của chương trình, vì bí danh hoạt động giống như con trỏ ở một số khía cạnh. Ví dụ, việc truyền một đối tượng là rẻ vì quá trình thực hiện chỉ truyền một con trỏ;

9. 2. Phạm vi Python và không gian tên

Trước khi giới thiệu các lớp học, trước tiên tôi phải nói với bạn đôi điều về quy tắc phạm vi của Python. Định nghĩa lớp chơi một số thủ thuật gọn gàng với không gian tên và bạn cần biết cách phạm vi và không gian tên hoạt động để hiểu đầy đủ những gì đang diễn ra. Ngẫu nhiên, kiến ​​thức về chủ đề này rất hữu ích cho bất kỳ lập trình viên Python nâng cao nào

Hãy bắt đầu với một số định nghĩa

Một không gian tên là ánh xạ từ tên đến đối tượng. Hầu hết các không gian tên hiện được triển khai dưới dạng từ điển Python, nhưng điều đó thường không đáng chú ý theo bất kỳ cách nào [ngoại trừ hiệu suất] và nó có thể thay đổi trong tương lai. Ví dụ về không gian tên là. tập hợp các tên dựng sẵn [chứa các hàm như và các tên ngoại lệ dựng sẵn]; . Theo một nghĩa nào đó, tập hợp các thuộc tính của một đối tượng cũng tạo thành một không gian tên. Điều quan trọng cần biết về các không gian tên là hoàn toàn 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;

Nhân tiện, tôi sử dụng thuộc tính từ cho bất kỳ tên nào sau dấu chấm — ví dụ: trong biểu thức

class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
2,
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
3 là một thuộc tính của đối tượng
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
4. Nói một cách chính xác, các tham chiếu đến tên trong các mô-đun là các tham chiếu thuộc tính. trong biểu thức
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
5,
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
6 là một đối tượng mô-đun và
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
7 là một thuộc tính của nó. Trong trường hợp này, có một ánh xạ đơn giản giữa các thuộc tính của mô-đun và tên chung được xác định trong mô-đun. họ chia sẻ cùng một không gian tên.

Các thuộc tính có thể là chỉ đọc hoặc ghi. Trong trường hợp sau, có thể gán cho các thuộc tính. Thuộc tính mô-đun có thể ghi. bạn có thể viết

class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
8. Các thuộc tính có thể ghi cũng có thể bị xóa bằng câu lệnh. Ví dụ:
x = MyClass[]
0 sẽ xóa thuộc tính
x = MyClass[]
1 khỏi đối tượng được đặt tên bởi
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
6

Không gian tên được tạo tại các thời điểm khác nhau và có thời gian tồn tại khác nhau. Không gian tên chứa tên dựng sẵn được tạo khi trình thông dịch Python khởi động và không bao giờ bị xóa. Không gian tên chung cho một mô-đun được tạo khi định nghĩa mô-đun được đọc vào; . Các câu lệnh được thực thi bởi lệnh gọi cấp cao nhất của trình thông dịch, được đọc từ tệp tập lệnh hoặc tương tác, được coi là một phần của mô-đun có tên , vì vậy chúng có không gian tên chung của riêng chúng. [Các tên dựng sẵn thực sự cũng tồn tại trong một mô-đun; cái này được gọi là. ]

Không gian tên cục bộ cho một hàm được tạo khi hàm được gọi và bị xóa khi hàm trả về hoặc đưa ra một ngoại lệ không được xử lý trong hàm. [Thật ra, quên sẽ là cách tốt hơn để mô tả những gì thực sự xảy ra. ] Tất nhiên, mỗi lời gọi đệ quy đều có không gian tên cục bộ của riêng chúng

Phạm vi là một vùng văn bản của chương trình Python nơi không gian tên có thể truy cập trực tiếp. “Có thể truy cập trực tiếp” ở đây có nghĩa là một tham chiếu không đủ tiêu chuẩn đến một tên cố gắng tìm tên đó trong không gian tên

Mặc dù phạm vi được xác định tĩnh nhưng chúng được sử dụng động. Bất cứ lúc nào trong quá trình thực thi, có 3 hoặc 4 phạm vi lồng nhau có không gian tên có thể truy cập trực tiếp

  • phạm vi trong cùng, được tìm kiếm đầu tiên, chứa tên địa phương

  • phạm vi của bất kỳ chức năng kèm theo nào, được tìm kiếm bắt đầu bằng phạm vi kèm theo gần nhất, chứa các tên không cục bộ, nhưng cũng không phải toàn cầu

  • phạm vi next-to-last chứa tên chung của mô-đun hiện tại

  • phạm vi ngoài cùng [được tìm kiếm cuối cùng] là không gian tên chứa các tên dựng sẵn

Nếu một tên được khai báo là toàn cầu, thì tất cả các tham chiếu và phép gán sẽ chuyển trực tiếp đến phạm vi tiếp theo chứa tên toàn cục của mô-đun. Để rebind các biến được tìm thấy bên ngoài phạm vi trong cùng, câu lệnh có thể được sử dụng;

Thông thường, phạm vi cục bộ tham chiếu tên cục bộ của hàm hiện tại [theo văn bản]. Các chức năng bên ngoài, phạm vi cục bộ tham chiếu cùng một không gian tên với phạm vi toàn cầu. không gian tên của mô-đun. Định nghĩa lớp đặt một không gian tên khác trong phạm vi cục bộ

Điều quan trọng là phải nhận ra rằng phạm vi được xác định theo văn bản. phạm vi toàn cầu của một chức năng được xác định trong một mô-đun là không gian tên của mô-đun đó, bất kể chức năng được gọi từ đâu hoặc bằng bí danh nào. Mặt khác, việc tìm kiếm tên thực tế được thực hiện một cách linh hoạt, trong thời gian chạy — tuy nhiên, định nghĩa ngôn ngữ đang phát triển theo hướng phân giải tên tĩnh, tại thời điểm “biên dịch”, vì vậy đừng dựa vào độ phân giải tên động. [Thực tế, các biến cục bộ đã được xác định tĩnh. ]

Một điều đặc biệt của Python là - nếu không có hoặc câu lệnh nào có hiệu lực - việc gán cho các tên luôn đi vào phạm vi trong cùng. Bài tập không sao chép dữ liệu — chúng chỉ liên kết tên với đối tượng. Điều này cũng đúng với việc xóa. câu lệnh

x = MyClass[]
8 xóa ràng buộc của
x = MyClass[]
9 khỏi không gian tên được tham chiếu bởi phạm vi cục bộ. Trên thực tế, tất cả các hoạt động giới thiệu tên mới đều sử dụng phạm vi cục bộ. đặc biệt, các câu lệnh và định nghĩa hàm liên kết tên mô-đun hoặc hàm trong phạm vi cục bộ

Câu lệnh có thể được sử dụng để chỉ ra rằng các biến cụ thể tồn tại trong phạm vi toàn cầu và sẽ được phục hồi ở đó;

9. 2. 1. Ví dụ về phạm vi và không gian tên

Đây là một ví dụ minh họa cách tham chiếu các phạm vi và không gian tên khác nhau cũng như cách thức và ảnh hưởng đến liên kết biến

def scope_test[]:
    def do_local[]:
        spam = "local spam"

    def do_nonlocal[]:
        nonlocal spam
        spam = "nonlocal spam"

    def do_global[]:
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local[]
    print["After local assignment:", spam]
    do_nonlocal[]
    print["After nonlocal assignment:", spam]
    do_global[]
    print["After global assignment:", spam]

scope_test[]
print["In global scope:", spam]

Đầu ra của mã ví dụ là

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

Lưu ý cách gán cục bộ [mặc định] không thay đổi ràng buộc spam của scope_test. Nhiệm vụ đã thay đổi ràng buộc thư rác của scope_test và nhiệm vụ đã thay đổi ràng buộc cấp mô-đun

Bạn cũng có thể thấy rằng không có ràng buộc nào đối với thư rác trước khi chuyển nhượng

9. 3. Cái nhìn đầu tiên về lớp học

Các lớp giới thiệu một chút cú pháp mới, ba loại đối tượng mới và một số ngữ nghĩa mới

9. 3. 1. Cú pháp định nghĩa lớp

Hình thức định nghĩa lớp đơn giản nhất trông như thế này

class ClassName:
    
    .
    .
    .
    

Các định nghĩa lớp, như định nghĩa hàm [các câu lệnh] phải được thực thi trước khi chúng có bất kỳ tác dụng nào. [Bạn có thể đặt một định nghĩa lớp trong một nhánh của câu lệnh hoặc bên trong một hàm. ]

Trong thực tế, các câu lệnh bên trong một định nghĩa lớp thường sẽ là các định nghĩa hàm, nhưng các câu lệnh khác được cho phép và đôi khi hữu ích — chúng ta sẽ quay lại vấn đề này sau. Các định nghĩa hàm bên trong một lớp thường có một dạng danh sách đối số đặc biệt, được quy định bởi các quy ước gọi phương thức — một lần nữa, điều này sẽ được giải thích sau

Khi một định nghĩa lớp được nhập, một không gian tên mới được tạo và được sử dụng làm phạm vi cục bộ — do đó, tất cả các phép gán cho các biến cục bộ đều đi vào vùng tên mới này. Cụ thể, các định nghĩa hàm liên kết tên của hàm mới tại đây

Khi một định nghĩa lớp được để lại bình thường [thông qua phần cuối], một đối tượng lớp được tạo. Về cơ bản, đây là một trình bao bọc xung quanh nội dung của không gian tên được tạo bởi định nghĩa lớp; . Phạm vi cục bộ ban đầu [phạm vi có hiệu lực ngay trước khi định nghĩa lớp được nhập] được khôi phục và đối tượng lớp được liên kết ở đây với tên lớp được đưa ra trong tiêu đề định nghĩa lớp [trong ví dụ ___8_______0]

9. 3. 2. Đối tượng lớp

Các đối tượng lớp hỗ trợ hai loại hoạt động. tham chiếu thuộc tính và khởi tạo

Tham chiếu thuộc tính sử dụng cú pháp tiêu chuẩn được sử dụng cho tất cả các tham chiếu thuộc tính trong Python.

x = MyClass[]
1. Tên thuộc tính hợp lệ là tất cả các tên có trong không gian tên của lớp khi đối tượng lớp được tạo. Vì vậy, nếu định nghĩa lớp trông như thế này

class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'

thì

x = MyClass[]
2 và
x = MyClass[]
3 là các tham chiếu thuộc tính hợp lệ, trả về một số nguyên và một đối tượng hàm tương ứng. Các thuộc tính của lớp cũng có thể được gán cho, vì vậy bạn có thể thay đổi giá trị của
x = MyClass[]
2 bằng cách gán.
x = MyClass[]
5 cũng là một thuộc tính hợp lệ, trả về chuỗi tài liệu thuộc về lớp.
x = MyClass[]
6

Khởi tạo lớp sử dụng ký hiệu hàm. Chỉ giả vờ rằng đối tượng lớp là một hàm không tham số trả về một thể hiện mới của lớp. Ví dụ [giả sử lớp trên]

________số 8_______

tạo một thể hiện mới của lớp và gán đối tượng này cho biến cục bộ

x = MyClass[]
9

Thao tác khởi tạo [“gọi” một đối tượng lớp] tạo một đối tượng trống. Nhiều lớp muốn tạo các đối tượng với các thể hiện được tùy chỉnh theo trạng thái ban đầu cụ thể. Do đó, một lớp có thể định nghĩa một phương thức đặc biệt có tên là

x = MyClass[]
8, như thế này

def __init__[self]:
    self.data = []

Khi một lớp định nghĩa một phương thức

x = MyClass[]
8, việc khởi tạo lớp sẽ tự động gọi
x = MyClass[]
8 cho thể hiện của lớp mới được tạo. Vì vậy, trong ví dụ này, một phiên bản mới, được khởi tạo có thể được lấy bằng cách

________số 8_______

Tất nhiên, phương pháp

x = MyClass[]
8 có thể có các đối số để linh hoạt hơn. Trong trường hợp đó, các đối số được cung cấp cho toán tử khởi tạo lớp được chuyển đến
x = MyClass[]
8. Ví dụ,

>>> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]

9. 3. 3. Đối tượng dụ

Bây giờ chúng ta có thể làm gì với các đối tượng thể hiện? . Có hai loại tên thuộc tính hợp lệ. thuộc tính dữ liệu và phương pháp

thuộc tính dữ liệu tương ứng với “biến thể hiện” trong Smalltalk và với “thành viên dữ liệu” trong C++. Thuộc tính dữ liệu không cần khai báo; . Ví dụ: nếu

x = MyClass[]
9 là phiên bản của
>>> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
4 được tạo ở trên, đoạn mã sau sẽ in giá trị
>>> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
5 mà không để lại dấu vết

x.counter = 1
while x.counter >> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
6 là một tham chiếu phương thức hợp lệ, vì
x = MyClass[]
3 là một hàm, nhưng
>>> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
8 thì không, vì
x = MyClass[]
2 không phải. Nhưng
>>> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
6 không giống với
x = MyClass[]
3 — nó là đối tượng phương thức, không phải đối tượng hàm

9. 3. 4. Đối tượng phương thức

Thông thường, một phương thức được gọi ngay sau khi nó bị ràng buộc

x.f[]

Trong ví dụ

>>> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
4, điều này sẽ trả về chuỗi
x.counter = 1
while x.counter >> class Complex:
..     def __init__[self, realpart, imagpart]:
..         self.r = realpart
..         self.i = imagpart
...
>>> x = Complex[3.0, -4.5]
>>> x.r, x.i
[3.0, -4.5]
6 là một đối tượng phương thức và có thể được lưu trữ và gọi sau. Ví dụ

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
0

sẽ tiếp tục in

x.counter = 1
while x.counter 

Chủ Đề