Hướng dẫn python function parameter class object - đối tượng lớp tham số hàm python

Tùy thuộc vào việc bạn có ý định vượt qua một lớp [loại] hay một thể hiện của một lớp, bạn đã tìm kiếm

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
7 hoặc đơn giản là lớp.

Ở đây, một ví dụ đơn giản để giải thích cả hai tình huống:

from typing import Type, TypeVar


class Vehicle:
    def __init__[self]:
        print["Creating a %s" % self.__class__.__name__]

    def move[self]:
        print["This %s is moving…" % self.__class__.__name__]

TVehicle = TypeVar["TVehicle", bound=Vehicle]

class Car[Vehicle]:
    def honk[self] -> None:
        print["tuuuuut"]

class Bike[Vehicle]:
    def ring[self] -> None:
        print["ring"]

class Dog:
    def bark[self] -> None:
        print["woof!"]


def move[v: Vehicle] -> None:
    v.move[]

def instantiate[class_to_instantiate: Type[TVehicle]] -> TVehicle:
    return class_to_instantiate[]  # create an instance

move[Bike[]]
move[Car[]]

instantiate[Bike].ring[]
instantiate[Car].honk[]
#instantiate[Dog]

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
8 và
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
9 kế thừa từ
class ClassName:
    
    .
    .
    .
    
0, vì vậy cả hai đều nhận được ít nhất phương thức
class ClassName:
    
    .
    .
    .
    
1 và tùy chỉnh
class ClassName:
    
    .
    .
    .
    
2, cho thấy tên của lớp đã gọi nó.

Bây giờ, trong hàm đầu tiên,

class ClassName:
    
    .
    .
    .
    
1, người ta chỉ muốn chỉ định rằng đối số
class ClassName:
    
    .
    .
    .
    
4 phải là một ví dụ của
class ClassName:
    
    .
    .
    .
    
0. Hàm gọi phương thức ____ 30 30 ____ ____31, sẽ tiết lộ tên của lớp thể hiện mà từ đó cuộc gọi bắt nguồn.

Trong hàm thứ hai,

class ClassName:
    
    .
    .
    .
    
8, mục tiêu là tạo ra một thể hiện của một lớp. Điều này hoạt động thông qua các biến loại, cho phép bạn trong ví dụ này chỉ định rằng có mối quan hệ giữa đối số đầu vào của hàm và đối số đầu ra: Nếu tôi gọi
class ClassName:
    
    .
    .
    .
    
9, tôi muốn loại trả về là một thể hiện của lớp
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
9, để điều đó Tôi có thể gọi một cách hợp pháp phương thức
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
1 của nó. Nếu bạn thay thế
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
2 trong định nghĩa chức năng này chỉ bằng
class ClassName:
    
    .
    .
    .
    
0, chương trình kiểm tra loại của bạn sẽ phàn nàn, vì loại trả về sau đó sẽ là một ví dụ của lớp
class ClassName:
    
    .
    .
    .
    
0 mà bạn không có đảm bảo rằng phương thức
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
1 tồn tại. Cuối cùng, phần
class MyClass:
    """A simple example class"""
    i = 12345

    def f[self]:
        return 'hello world'
6 mà bạn thấy trong đối số của
class ClassName:
    
    .
    .
    .
    
8 chỉ đơn giản cho phép bạn gọi chức năng với một lớp, vì vậy không phải là một thể hiện của lớp đó. Điều này rất hữu ích, ví dụ: Trong trường hợp bạn muốn trì hoãn việc khởi tạo một lớp.

Lưu ý rằng đây là một ví dụ để giải thích cách làm điều đó. Trong một môi trường chuyên nghiệp hơn,

class ClassName:
    
    .
    .
    .
    
0 có thể sẽ là một lớp cơ sở trừu tượng và một số phương pháp ở đây có thể được đưa ra dưới dạng phương pháp lớp.

Ghi chú bên trên mã của bạn Ví dụ:

  1. Lưu ý rằng nếu bạn không có ý định viết mã cũng hoạt động trong Python2, bạn không nên kế thừa từ
    class MyClass:
        """A simple example class"""
        i = 12345
    
        def f[self]:
            return 'hello world'
    
    9 [ref].
  2. Các lớp thường được viết bằng các tên
    def __init__[self]:
        self.data = []
    
    0, như được chỉ định trong PEP8, Hướng dẫn kiểu Python. Theo phong cách này làm cho mã của bạn dễ hiểu hơn bởi các nhà phát triển khác.

Các lớp cung cấp một phương tiện của dữ liệu bó và chức năng cùng nhau. Tạo một lớp mới tạo ra một loại đối tượng mới, cho phép các phiên bản mới của loại đó được thực hiện. Mỗi phiên bản lớp có thể có các thuộc tính được gắn vào nó để duy trì trạng thái của nó. Các phiên bản lớp cũng có thể có các phương thức [được xác định 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 Python, bổ sung các lớp có tối thiểu cú pháp mới và ngữ nghĩa. Nó là một hỗn hợp của các cơ chế lớp được tìm thấy 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 lớp của nó và một phương thức có thể gọi phương thức của một 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 ý. Là đúng với các mô -đun, các lớp chia tay bản chất động của Python: chúng được tạo ra trong thời gian chạy và có thể được sửa đổi hơn nữa sau khi tạo.

Trong thuật ngữ C ++, thông thường các thành viên lớp [bao gồm các thành viên dữ liệu] là công khai [ngoại trừ xem bên dưới các biến riêng tư] và tất cả các hàm thành viên là ảo. Như trong Modula-3, không có chữ viết tắt nào để tham khảo các thành viên của đối tượng từ các phương thức của nó: hàm phương thức đượ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 hoàn toàn bởi cuộc gọi. Như trong Smalltalk, bản thân các lớp là đối tượng. Điều này cung cấp ngữ nghĩa để nhập khẩu và đổi tên. Không giống như C ++ và Modula-3, các loại tích hợp có thể được sử dụng làm lớp cơ sở để mở rộng bởi 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 với cú pháp đặc biệt [toán tử số học, đăng ký, v.v.] có thể được xác định lại cho các trường hợp lớp.Private Variables], and all member functions are virtual. As in Modula-3, there are no shorthands for referencing the object’s members from its methods: the method function is declared with an explicit first argument representing the object, which is provided implicitly by the call. As in Smalltalk, classes themselves are objects. This provides semantics for importing and renaming. Unlike C++ and Modula-3, built-in types can be used as base classes for extension by the user. Also, like in C++, most built-in operators with special syntax [arithmetic operators, subscripting etc.] can be redefined for class instances.

. đã nghe nói về nó.]

9.1. Một từ về tên và đối tượngA Word About Names and Objects¶

Các đối tượng có tính cá nhân 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 tại Python và có thể bị bỏ qua một cách an toàn khi xử lý các loại cơ bản bất biến [số, chuỗi, bộ dữ liệu]. Tuy nhiên, bí danh có tác dụ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 cho lợi ích của chương trình, vì các bí danh hoạt động như con trỏ ở một số khía cạnh. Ví dụ, việc chuyển một đối tượng là rẻ vì chỉ có một con trỏ được thông qua khi thực hiện; Và nếu một hàm sửa đổi một đối tượng được truyền như một đối số, người gọi sẽ thấy sự thay đổi - điều này sẽ loại bỏ sự cần thiết của hai cơ chế truyền đối số khác nhau như trong Pascal.

9.2. Phạm vi Python và không gian tênPython Scopes and Namespaces¶

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ều gì đó về các quy tắc phạm vi Python. Các định nghĩa củ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ì xảy 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 tiên tiến nào.

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

Một không gian tên là một ánh xạ từ tên đến các đối tượng. Hầu hết các không gian tên hiện đang đượ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ề các không gian tên là: tập hợp các tên tích hợp [chứa các hàm như

def __init__[self]:
    self.data = []
1 và tên ngoại lệ tích hợp]; tên toàn cầu trong một mô -đun; và tên địa phương trong một lời cầu khẩn chức năng. 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ệ giữa các tên trong các không gian tên khác nhau; Chẳng hạn, hai mô -đun khác nhau đều có thể xác định hàm
def __init__[self]:
    self.data = []
2 mà không có sự nhầm lẫn - người dùng của các mô -đun phải có tiền tố với tên mô -đun.

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

def __init__[self]:
    self.data = []
3,
def __init__[self]:
    self.data = []
4 là một thuộc tính của đối tượng
def __init__[self]:
    self.data = []
5. Nói đúng ra, các tham chiếu đến tên trong các mô -đun là tài liệu tham khảo thuộc tính: Trong biểu thức
def __init__[self]:
    self.data = []
6,
def __init__[self]:
    self.data = []
7 là một đối tượng mô -đun và
def __init__[self]:
    self.data = []
8 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 mô -đun và các tên toàn cầu được xác định trong mô -đun: chúng có chung không gian tên! 1

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

def __init__[self]:
    self.data = []
9. Các thuộc tính có thể ghi cũng có thể bị xóa với câu lệnh
>>> 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]
0. 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]
1 sẽ xóa thuộc tính
>>> 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]
2 khỏi đối tượng được đặt tên bởi
def __init__[self]:
    self.data = []
7.

Không gian tên được tạo ra vào những thời điểm khác nhau và có cuộc sống khác nhau. Không gian tên chứa các tên tích hợp đượ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 toàn cầu cho một mô -đun được tạo khi định nghĩa mô -đun được đọc trong; Thông thường, các không gian tên mô -đun cũng kéo dài cho đến khi thông dịch thoát. Các câu lệnh được thực hiện 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 gọi là

>>> 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, vì vậy chúng có không gian tên toàn cầu của riêng họ. [Các tên tích hợp thực sự cũng sống trong một mô-đun; cái này được gọi là
>>> 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.]

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 tăng một ngoại lệ không được xử lý trong hàm. .

Phạm vi là một khu vực 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 trực tiếp ở đây có nghĩa là một tham chiếu không đủ tiêu chuẩn cho 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, chúng được sử dụng động. Bất cứ lúc nào trong quá trình thực hiện, 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 trước, chứa tên địa phương

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

  • Phạm vi tiếp theo có chứa các tên toàn cầu hiện tại của mô-đun

  • Phạm vi ngoài cùng [được tìm kiếm cuối cùng] là không gian tên chứa tên tích hợp

Nếu một tên được khai báo toàn cầu, thì tất cả các tài liệu tham khảo và bài tập sẽ trực tiếp đến phạm vi giữa chứa các tên toàn cầu của mô -đun. Để tái lập các biến được tìm thấy bên ngoài phạm vi trong cùng, câu lệnh

>>> 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 có thể được sử dụng; Nếu không được tuyên bố là không thuộc địa, các biến đó chỉ được đọc [một nỗ lực ghi vào một biến như vậy sẽ chỉ đơn giản là tạo một biến cục bộ mới trong phạm vi trong cùng, để lại biến bên ngoài có tên giống hệt nhau].

Thông thường, phạm vi cục bộ tham chiếu tên cục bộ của hàm [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 mô -đun. Định nghĩa lớp đặt một không gian tên khác trong phạm vi địa phương.

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

Một câu đố đặc biệt của Python là - nếu không có tuyên bố

>>> 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]
7 hoặc
>>> 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 có hiệu lực - bài tập 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 các đối tượng. Điều tương tự cũng đúng với việc xóa: Tuyên bố
>>> 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 loại bỏ liên kết của
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]
7 có thể được sử dụng để chỉ ra rằng các biến cụ thể sống trong phạm vi toàn cầu và nên được bật lại ở đó; Tuyên bố
>>> 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 chỉ ra rằng các biến cụ thể sống trong một phạm vi kèm theo và nên được bật lại ở đó.

9.2.1. Phạm vi và không gian tên ví dụScopes and Namespaces Example¶

Đây là một ví dụ chứng minh cách tham chiếu các phạm vi và không gian tên khác nhau và cách

>>> 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]
7 và
>>> 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 ảnh hưởng đến ràng buộc 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 liên kết thư rác của Scope_test. Bài tập

>>> 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 đã thay đổi liên kết spam của Scope_test và gán
>>> 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]
7 đã thay đổi liên kết cấp độ mô-đun.

Bạn cũng có thể thấy rằng không có ràng buộc trước đó cho thư rác trước khi gán

>>> 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]
7.

9.3. Cái nhìn đầu tiên về các lớp họcA First Look at Classes¶

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. Định nghĩa lớp cú phápClass Definition Syntax¶

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

class ClassName:
    
    .
    .
    .
    

Định nghĩa lớp, giống như định nghĩa hàm [câu lệnh

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]

9.3.3. Đối tượng thể hiệnInstance Objects¶

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

Các thuộc tính dữ liệu tương ứng với các biến thể hiện của các biến thể trong số các thành viên dữ liệu và các thành viên dữ liệu của người Hồi giáo trong C ++. Thuộc tính dữ liệu không cần phải được khai báo; Giống như các biến cục bộ, chúng sinh ra sự tồn tại khi chúng được gán lần đầu tiên. Ví dụ: nếu

x.counter = 1
while x.counter >> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
5 được tạo ở trên, đoạn mã sau sẽ in giá trị
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__[self, name]:
        self.name = name    # instance variable unique to each instance

>>> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
6, mà không để lại dấu vết:

x.counter = 1
while x.counter >> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
7 là một tham chiếu phương thức hợp lệ, vì
xf = x.f
while True:
    print[xf[]]
4 là một hàm, nhưng
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__[self, name]:
        self.name = name    # instance variable unique to each instance

>>> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
9 thì không, vì
xf = x.f
while True:
    print[xf[]]
3 thì không. Nhưng
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__[self, name]:
        self.name = name    # instance variable unique to each instance

>>> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
7 không giống như
xf = x.f
while True:
    print[xf[]]
4 - đó là một đối tượng phương thức, không phải là đối tượng hàm.

9.3.4. Phương pháp đối tượng JoMethod Objects¶

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

Trong ví dụ

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__[self, name]:
        self.name = name    # instance variable unique to each instance

>>> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
5, điều này sẽ trả về chuỗi
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]
04. Tuy nhiên, không cần thiết phải gọi một phương thức ngay lập tức:
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__[self, name]:
        self.name = name    # instance variable unique to each instance

>>> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'
7 là một đối tượng phương thức và có thể được lưu trữ và gọi sau đó. Ví dụ:

xf = x.f
while True:
    print[xf[]]

sẽ tiếp tục in

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]
06 cho đến cuối thời gian.

Điều gì chính xác xảy ra khi một phương thức được gọi là? Bạn có thể nhận thấy rằng

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]
07 đã được gọi mà không có đối số ở trên, mặc dù định nghĩa hàm cho
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]
08 đã chỉ định một đối số. Điều gì đã xảy ra với cuộc tranh luận? Chắc chắn Python nêu ra một ngoại lệ khi một hàm yêu cầu một đối số được gọi là không có bất kỳ - ngay cả khi đối số không thực sự được sử dụng

Trên thực tế, bạn có thể đã đoán câu trả lời: Điều đặc biệt về các phương thức là đối tượng thể hiện được truyền như là đối số đầu tiên của hàm. Trong ví dụ của chúng tôi, cuộc gọi

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]
07 hoàn toàn tương đương với
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]
10. Nói chung, gọi một phương thức có danh sách N đối số tương đương với việc gọi hàm tương ứng với danh sách đối số được tạo bằng cách chèn đối tượng phiên bản Phương thức trước đối số đầu tiên.

Nếu bạn vẫn không hiểu cách thức hoạt động của các phương pháp, một cái nhìn về việc triển khai có thể làm rõ vấn đề. Khi một thuộc tính không dữ liệu của một thể hiện được tham chiếu, lớp thể hiện được tìm kiếm. Nếu tên biểu thị thuộc tính lớp hợp lệ là đối tượng hàm, đối tượng phương thức được tạo bằng cách đóng gói [con trỏ đến] đối tượng thể hiện và đối tượng hàm chỉ được tìm thấy cùng nhau trong một đối tượng trừu tượng: đây là đối tượng phương thức. Khi đối tượng Phương thức được gọi với danh sách đối số, một danh sách đối số mới được xây dựng từ đối tượng phiên bản và danh sách đối số và đối tượng hàm được gọi với danh sách đối số mới này.

9.3.5. Biến lớp và phiên bảnClass and Instance Variables¶

Nói chung, các biến thể hiện là cho dữ liệu duy nhất cho từng trường hợp và biến lớp dành cho các thuộc tính và phương thức được chia sẻ bởi tất cả các trường hợp của lớp:

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__[self, name]:
        self.name = name    # instance variable unique to each instance

>>> d = Dog['Fido']
>>> e = Dog['Buddy']
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'

Như đã thảo luận trong một từ về tên và đối tượng, dữ liệu được chia sẻ có thể có các hiệu ứng đáng ngạc nhiên với liên quan đến các đối tượng có thể thay đổi như danh sách và từ điển. Ví dụ: danh sách thủ thuật trong mã sau không nên được sử dụng làm biến lớp vì chỉ một danh sách duy nhất sẽ được chia sẻ bởi tất cả các trường hợp chó:A Word About Names and Objects, shared data can have possibly surprising effects with involving mutable objects such as lists and dictionaries. For example, the tricks list in the following code should not be used as a class variable because just a single list would be shared by all Dog instances:

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]
0

Thay vào đó, thiết kế chính xác của lớp nên sử dụng biến thể hiệ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]
1

9.4. Nhận xét ngẫu nhiênRandom Remarks¶

Nếu cùng một tên thuộc tính xảy ra trong cả một thể hiện và trong một lớp, thì tra cứu thuộc tính ưu tiên thể hiệ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]
2

Các thuộc tính dữ liệu có thể được tham chiếu bằng các phương thức cũng như bởi người dùng thông thường [máy khách trực tuyến] của một đối tượng. Nói cách khác, các lớp không thể sử dụng để thực hiện các loại dữ liệu trừu tượng thuần túy. Trên thực tế, không có gì trong Python làm cho nó có thể thực thi ẩn dữ liệu - tất cả đều dựa trên quy ước. .

Khách hàng nên sử dụng các thuộc tính dữ liệu cẩn thận - Khách hàng có thể làm rối loạn các bất biến được duy trì bằng các phương thức bằng cách dán vào các thuộc tính dữ liệu của họ. Lưu ý rằng khách hàng có thể thêm các thuộc tính dữ liệu của riêng họ vào một đối tượng thể hiện mà không ảnh hưởng đến tính hợp lệ của các phương thức, miễn là tránh xung đột tên - một lần nữa, một quy ước đặt tên có thể tiết kiệm rất nhiều vấn đề đau đầu ở đây.

Không có tốc ký để tham khảo các thuộc tính dữ liệu [hoặc các phương thức khác!] Từ bên trong các phương thức. Tôi thấy rằng điều này thực sự làm tăng khả năng đọc của các phương pháp: không có cơ hội nhầm lẫn các biến cục bộ và biến thể hiện khi liếc qua một phương thức.

Thông thường, đối số đầu tiên của một phương thức được gọi là

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]
11. Đây không gì khác hơn là một quy ước: cái tê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]
11 hoàn toàn không có ý nghĩa đặc biệt đối với Python. Tuy nhiên, lưu ý rằng bằng cách không tuân theo quy ước của bạn, mã của bạn có thể không thể đọc được đối với các lập trình viên Python khác và cũng có thể hình dung rằng một chương trình trình duyệt lớp có thể được viết dựa trên quy ước như vậy.

Bất kỳ đối tượng hàm nào là thuộc tính lớp xác định một phương thức cho các trường hợp của lớp đó. Không cần thiết phải định nghĩa hàm được đặt theo văn bản trong định nghĩa lớp: gán một đối tượng hàm cho biến cục bộ trong lớp cũng ổn. Ví dụ:

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]
3

Bây giờ

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]
13,
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]
14 và
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]
15 đều là các thuộc tính của lớp
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]
16 đề cập đến các đối tượng chức năng và do đó chúng đều là phương pháp của các trường hợp của
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]
16 -
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]
15 tương đương với
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]
14. Lưu ý rằng thực tế này thường chỉ phục vụ để gây nhầm lẫn cho người đọc của một chương trình.

Các phương thức có thể gọi các phương thức khác bằng cách sử dụng các thuộc tính phương thức của đối số

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]
11:

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]
4

Các phương thức có thể tham chiếu tên toàn cầu theo cách tương tự như các hàm thông thường. Phạm vi toàn cầu được liên kết với một phương thức là mô -đun chứa định nghĩa của nó. . được sử dụng bởi các phương pháp, cũng như các chức năng và các lớp được xác định trong đó. Thông thường, lớp chứa phương thức được xác định trong phạm vi toàn cầu này và trong phần tiếp theo, chúng tôi sẽ tìm thấy một số lý do chính đáng tại sao một phương thức muốn tham chiếu lớp của chính nó.

Mỗi giá trị là một đối tượng và do đó có một lớp [còn được gọi là loại của nó]. Nó được lưu trữ dưới dạng

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]
21.

9,5. Di sản¶Inheritance¶

Tất nhiên, một tính năng ngôn ngữ sẽ không xứng đáng với cái tên là lớp học mà không hỗ trợ thừa kế. Cú pháp cho một định nghĩa lớp dẫn xuất trông như thế này:

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]
5

Tê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]
22 phải được xác định trong một phạm vi chứa định nghĩa lớp dẫn xuất. Thay cho một tên lớp cơ sở, các biểu thức tùy ý khác cũng được cho phép. Điều này có thể hữu ích, ví dụ, khi lớp cơ sở được xác định trong một mô -đun khác:

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]
6

Việc thực hiện một định nghĩa lớp dẫn xuất tiến hành giống như đối với một lớp cơ sở. Khi đối tượng lớp được xây dựng, lớp cơ sở được ghi nhớ. Điều này được sử dụng để giải quyết các tài liệu tham khảo thuộc tính: nếu một thuộc tính được yêu cầu không được tìm thấy trong lớp, tìm kiếm sẽ tiến hành tìm kiếm trong lớp cơ sở. Quy tắc này được áp dụng đệ quy nếu bản thân lớp cơ sở có nguồn gốc từ một số lớp khác.

Không có gì đặc biệt về việc khởi tạo các lớp dẫn xuất:

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]
23 tạo ra một thể hiện mới của lớp. Các tham chiếu phương thức được giải quyết như sau: Thuộc tính lớp tương ứng được tìm kiếm, giảm xuống chuỗi các lớp cơ sở nếu cần thiết và tham chiếu phương thức là hợp lệ nếu điều này mang lại một đối tượng hàm.

Các lớp dẫn xuất có thể ghi đè các phương thức của các lớp cơ sở của họ. Bởi vì các phương thức không có đặc quyền đặc biệt khi gọi các phương thức khác của cùng một đối tượng, một phương thức của một lớp cơ sở gọi một phương thức khác được xác định trong cùng một lớp cơ sở có thể gọi một phương thức của một lớp dẫn xuất ghi đè nó. [Đối với các lập trình viên C ++: Tất cả các phương thức trong Python đều có hiệu quả

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]
24.]

Trên thực tế, một phương thức ghi đè trong một lớp dẫn xuất có thể muốn mở rộng thay vì chỉ thay thế phương thức lớp cơ sở cùng tên. Có một cách đơn giản để gọi trực tiếp phương thức lớp cơ sở: chỉ cần gọi

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]
25. Điều này đôi khi cũng hữu ích cho khách hàng. [Lưu ý rằng điều này chỉ hoạt động nếu lớp cơ sở có thể truy cập là
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]
22 trong phạm vi toàn cầu.]

Python có hai chức năng tích hợp hoạt động với kế thừa:

  • Sử dụng

    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]
    
    27 để kiểm tra loại phiên bản loại:
    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]
    
    28 sẽ chỉ là ____129 nếu
    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]
    
    30 là
    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]
    
    31 hoặc một số lớp có nguồn gốc từ
    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]
    
    31.

  • Sử dụng

    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]
    
    33 để kiểm tra kế thừa lớp:
    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]
    
    34 là
    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]
    
    29 vì
    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]
    
    36 là một lớp con của
    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]
    
    31. Tuy nhiê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]
    
    38 là
    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]
    
    39 vì
    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]
    
    40 không phải là một lớp con của
    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]
    
    31.

9.5.1. Nhiều kế thừaMultiple Inheritance¶

Python cũng hỗ trợ một hình thức thừa kế. Một định nghĩa lớp với nhiều lớp cơ sở trông như thế này:

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]
7

Đối với hầu hết các mục đích, trong các trường hợp đơn giản nhất, bạn có thể nghĩ về việc tìm kiếm các thuộc tính được kế thừa từ lớp cha là độ sâu đầu tiên, từ trái sang phải, không tìm kiếm hai lần trong cùng một lớp, nơi có sự chồng chéo trong hệ thống phân cấp. Do đó, nếu một thuộc tính không được tìm thấy trong

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]
42, nó sẽ được tìm kiếm trong
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]
43, thì [đệ quy] trong các lớp cơ sở là
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]
43, và nếu nó không được tìm thấy ở đó, nó đã được tìm kiếm trong
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]
45, v.v.

Trong thực tế, nó phức tạp hơn một chút; Thứ tự giải quyết phương thức thay đổi linh hoạt để hỗ trợ các cuộc gọi hợp tác đế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]
46. Cách tiếp cận này được biết đến trong một số ngôn ngữ đa bảo vệ khác là phương pháp call-next và mạnh hơn so với siêu gọi được tìm thấy trong các ngôn ngữ đơn lẻ.

Đặt hàng động là cần thiết bởi vì tất cả các trường hợp di truyền đều thể hiện một hoặc nhiều mối quan hệ kim cương [trong đó ít nhất một trong các lớp cha mẹ có thể được truy cập thông qua nhiều đường dẫn từ lớp Bottommost]. Ví dụ, tất cả các lớp kế thừa từ

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]
47, do đó, bất kỳ trường hợp nào của nhiều kế thừa đều cung cấp nhiều hơn một đường dẫn để đạt được
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]
47. Để giữ cho các lớp cơ sở không được truy cập nhiều lần, thuật toán động tuyến tính hóa thứ tự tìm kiếm theo cách bảo tồn thứ tự từ trái sang phải được chỉ định trong mỗi lớp, chỉ gọi cho mỗi cha mẹ một lần và đó là đơn điệu [có nghĩa là Một lớp học có thể được phân lớp mà không ảnh hưởng đến thứ tự ưu tiên của cha mẹ]. Kết hợp lại với nhau, các thuộc tính này cho phép thiết kế các lớp đáng tin cậy và có thể mở rộng với nhiều kế thừa. Để biết thêm chi tiết, xem //www.python.org/doad/releases/2.3/mro/.

9.6. Biến riêngPrivate Variables¶

Các biến thể riêng tư của người Viking không thể truy cập ngoại trừ từ bên trong một đối tượng don lồng tồn tại trong Python. Tuy nhiên, có một quy ước được theo sau bởi hầu hết các mã Python: một tên được đặt trước với dấu gạch dưới [ví dụ:

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]
49] nên được coi là một phần không công khai của API [cho dù đó là hàm, phương thức hoặc thành viên dữ liệu] . Nó nên được coi là một chi tiết thực hiện và có thể thay đổi mà không cần thông báo trước.

Vì có trường hợp sử dụng hợp lệ cho các thành viên tư nhân [cụ thể là để tránh các cuộc đụng độ tên có tên có tên được xác định bởi các lớp con], nên có sự hỗ trợ hạn chế cho một cơ chế như vậy, được gọi là tên Mangling. Bất kỳ định danh nào của Mẫu

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]
50 [ít nhất hai dấu gạch dưới hàng đầu, nhiều nhất là một dấu gạch dưới] được thay thế bằng văn bản bằng
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]
51, trong đó
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]
52 là tên lớp hiện tại với các dấu gạch dưới hàng đầu bị tước. Việc xáo trộn này được thực hiện mà không liên quan đến vị trí cú pháp của định danh, miễn là nó xảy ra trong định nghĩa của một lớp.

Tên Mangling rất hữu ích cho việc cho phép các lớp học ghi đè các phương thức mà không phá vỡ các cuộc gọi phương thức nội bộ. Ví dụ:

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]
8

Ví dụ trên sẽ hoạt động ngay cả khi

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]
53 sẽ giới thiệu một định danh
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]
54 vì nó được thay thế bằng
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]
55 trong lớp
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]
56 và
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]
57 trong lớp
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]
53 tương ứng.

Lưu ý rằng các quy tắc xáo trộn được thiết kế chủ yếu để tránh tai nạn; Vẫn có thể truy cập hoặc sửa đổi một biến được coi là riêng tư. Điều này thậm chí có thể hữu ích trong các trường hợp đặc biệt, chẳng hạn như trong trình gỡ lỗi.

Lưu ý rằng mã được chuyển đế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]
59 hoặc
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]
60 không coi tên lớp của lớp gọi là lớp hiện tại; Điều này tương tự như hiệu ứng của câu lệnh
>>> 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]
7, ảnh hưởng của nó cũng bị hạn chế đối với mã được biên dịch byte với nhau. Các hạn chế tương tự áp dụng cho
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]
62,
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]
63 và
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]
64, cũng như khi tham khảo trực tiếp
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]
65.

9.7. Vụn vặt¶Odds and Ends¶

Đôi khi, rất hữu ích khi có một loại dữ liệu tương tự như bản ghi của Pascal, hoặc Cv Struct Struct, kết hợp một vài mục dữ liệu được đặt tên. Một định nghĩa lớp trống sẽ làm độc đáo:

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]
9

Một đoạn mã Python mong đợi một loại dữ liệu trừu tượng cụ thể thường có thể được truyền một lớp mô phỏng các phương thức của kiểu dữ liệu đó. Chẳng hạn, nếu bạn có một hàm định dạng một số dữ liệu từ đối tượng tệp, bạn có thể xác định một lớp với các phương thức

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]
66 và
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]
67 lấy dữ liệu từ bộ đệm chuỗi thay thế và chuyển nó dưới dạng đối số.

Các đối tượng Phương thức thể hiện cũng có các thuộc tính:

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]
68 là đối tượng thể hiện với phương thức
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]
69 và
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]
70 là đối tượng hàm tương ứng với phương thức.

9.8. Tereratorators¶Iterators¶

Đến bây giờ, bạn có thể nhận thấy rằng hầu hết các đối tượng container có thể được lặp qua bằng cách sử dụng câu lệnh

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]
71:

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

Phong cách truy cập này là rõ ràng, súc tích và thuận tiện. Việc sử dụng các phép lặp lan tỏa và thống nhất Python. Đằng sau hậu trường, câu lệnh

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]
71 gọi
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]
73 trên đối tượng container. Hàm trả về một đối tượng lặp xác định phương thức
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]
74 truy cập vào các phần tử trong container cùng một lúc. Khi không có thêm các yếu tố,
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]
74 sẽ tăng ngoại lệ
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]
76 cho biết vòng lặp
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]
71 chấm dứt. Bạn có thể gọi phương thức
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]
74 bằng hàm tích hợp
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]
79; Ví dụ này cho thấy tất cả hoạt động như thế nào:

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

Đã nhìn thấy các cơ chế đằng sau giao thức Iterator, thật dễ dàng để thêm hành vi lặp lại vào các lớp của bạn. Xác định một phương thức

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]
80 trả về một đối tượng bằng phương thức
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]
74. Nếu lớp xác định
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]
74, thì
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]
80 chỉ có thể trả về
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]
11:

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

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

9.9. Máy phát điệnGenerators¶

Máy phát điện là một công cụ đơn giản và mạnh mẽ để tạo ra các trình lặp. Chúng được viết giống như các chức năng thông thường nhưng sử dụng câu lệnh

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]
85 bất cứ khi nào họ muốn trả về dữ liệu. Mỗi lầ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]
79 được gọi trên nó, trình tạo tiếp tục nơi nó rời đi [nó nhớ tất cả các giá trị dữ liệu và câu lệnh nào được thực hiện lần cuối]. Một ví dụ cho thấy rằng các máy phát điện có thể dễ dàng tạo ra: are a simple and powerful tool for creating iterators. They are written like regular functions but use the
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]
85 statement whenever they want to return data. Each time
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]
79 is called on it, the generator resumes where it left off [it remembers all the data values and which statement was last executed]. An example shows that generators can be trivially easy to create:

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

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

Bất cứ điều gì có thể được thực hiện với các trình tạo cũng có thể được thực hiện với các trình lặp dựa trên lớp như được mô tả trong phần trước. Điều làm cho các trình tạo trở nên nhỏ gọn là các phương thức

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]
80 và
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]
74 được tạo tự động.

Một tính năng quan trọng khác là các biến cục bộ và trạng thái thực thi được lưu tự động giữa các cuộc gọi. Điều này làm cho hàm dễ dàng hơn để viết và rõ ràng hơn nhiều so với cách tiếp cận sử dụng các biến thể hiện như

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]
89 và
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]
90.

Ngoài việc tạo và lưu trạng thái chương trình tiết kiệm phương thức tự động, khi các trình tạo chấm dứt, chúng tự động tăng

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]
76. Kết hợp lại, các tính năng này giúp bạn dễ dàng tạo ra các trình lặp không có nhiều nỗ lực hơn là viết một chức năng thông thường.

9.10. Biểu thức máy phátGenerator Expressions¶

Một số trình tạo đơn giản có thể được mã hóa ngắn gọn như các biểu thức bằng cách sử dụng cú pháp tương tự như các toàn bộ danh sách nhưng với dấu ngoặc đơn thay vì dấu ngoặc vuông. Các biểu thức này được thiết kế cho các tình huống mà trình tạo được sử dụng ngay lập tức bởi một hàm kèm theo. Biểu thức của máy phát là nhỏ gọn hơn nhưng ít linh hoạt hơn các định nghĩa của trình tạo đầy đủ và có xu hướng thân thiện với bộ nhớ hơn so với các toàn bộ danh sách tương đương.

Examples:

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

Chú thích

1

Ngoại trừ một điều. Các đối tượng mô-đun có một thuộc tính chỉ đọc bí mật gọi là

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]
65 trả về từ điển được sử dụng để thực hiện không gian tên mô-đun; Tê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]
65 là một thuộc tính nhưng không phải là một tên toàn cầu. Rõ ràng, việc sử dụng điều này vi phạm sự trừu tượng của việc thực hiện không gian tên và nên được giới hạn trong những thứ như gỡ lỗi sau khi chết.

Làm thế nào để bạn vượt qua một đối tượng lớp dưới dạng tham số trong Python?

Trong myClass có một phương pháp my_method có thêm một đối số khác ngoài bản thân. Trong người lớp, MyClass cũng được sử dụng để được nhập khẩu. Trong Phương thức Display [] đối tượng của MyClass được tạo. Sau đó, phương thức my_method [] của lớp myClass được gọi và đối tượng của lớp người được truyền dưới dạng tham số.

Chúng ta có thể chuyển các đối tượng lớp dưới dạng đối số chức năng trong Python không?

Có của thô, bạn có thể vượt qua các lớp hoặc chức năng hoặc thậm chí các mô -đun ... ...

Một lớp có thể có tham số python?

Lúc đầu, đối tượng lớp Python, bạn đặt tên của đối tượng mới được theo sau bởi toán tử gán và tên của lớp với các tham số [như được định nghĩa trong hàm tạo].Hãy nhớ rằng, số và loại tham số phải tương thích với các tham số nhận được trong hàm hàm tạo.you put the name of the new object which is followed by the assignment operator and the name of the class with parameters [as defined in the constructor]. Remember, the number and type of parameters should be compatible with the parameters received in the constructor function.

Hàm object [] trong python là gì?

Hàm python [] hàm hàm [] hàm trả về một đối tượng trống.Bạn không thể thêm các thuộc tính hoặc phương thức mới vào đối tượng này.Đối tượng này là cơ sở cho tất cả các lớp, nó giữ các thuộc tính và phương thức tích hợp mặc định cho tất cả các lớp.returns an empty object. You cannot add new properties or methods to this object. This object is the base for all classes, it holds the built-in properties and methods which are default for all classes.

Bài Viết Liên Quan

Chủ Đề