Hướng dẫn object and class attributes are accessed using notation in python - thuộc tính đối tượng và lớp được truy cập bằng ký hiệu trong python

Trong mã sau;

>>> class fooo[]:
        def __init__[self]:
            self.a=[]
>>> fooo[].a
    []
>>> fooo.a
    Traceback [most recent call last]:
      File "", line 1, in 
        fooo.a
    AttributeError: class fooo has no attribute 'a'

Tôi hơi nhầm lẫn về các ký hiệu fooo []. đang làm như:

>>> m=fooo[]
>>> m.a
[]

; Trong khi sử dụng ký hiệu fooo.a, chúng ta đang mong đợi A sẽ là một biến lớp/tĩnh? Tôi đúng hay nó là một cái gì đó khác?

Mark Hildreth

40.7k10 Huy hiệu vàng118 Huy hiệu bạc107 Huy hiệu đồng10 gold badges118 silver badges107 bronze badges

Hỏi ngày 28 tháng 9 năm 2013 lúc 19:02Sep 28, 2013 at 19:02

1

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
4 là một thuộc tính thể hiện. Nó có thể được truy cập bằng
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
5. Nhưng lưu ý rằng việc đó chỉ vứt bỏ thể hiện
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
6 được tạo ra; Một ví dụ hợp lý hơn là:

y = fooo[]
y.a = 5

Nó không tồn tại cho đến khi một thể hiện của lớp được tạo. Vâng, bạn hoàn toàn chính xác.

Đã trả lời ngày 28 tháng 9 năm 2013 lúc 19:26Sep 28, 2013 at 19:26

DarXtrixDarXtrixdarxtrix

1.9642 Huy hiệu vàng22 Huy hiệu bạc 30 Huy hiệu Đồng2 gold badges22 silver badges30 bronze badges

7.1. Lập trình hướng đối tượng¶Object-oriented programming¶

Python là ngôn ngữ lập trình hướng đối tượng, có nghĩa là nó cung cấp các tính năng hỗ trợ lập trình hướng đối tượng [OOP].object-oriented programming language, which means that it provides features that support object-oriented programming [ OOP].

Lập trình hướng đối tượng có nguồn gốc từ những năm 1960, nhưng đến giữa những năm 1980, nó trở thành mô hình lập trình chính được sử dụng trong việc tạo ra phần mềm mới. Nó được phát triển như một cách để xử lý kích thước và độ phức tạp tăng nhanh của các hệ thống phần mềm và để giúp việc sửa đổi các hệ thống lớn và phức tạp này theo thời gian dễ dàng hơn.

Cho đến nay chúng tôi đã viết các chương trình bằng cách sử dụng một mô hình lập trình thủ tục. Trong lập trình thủ tục, trọng tâm là viết các chức năng hoặc thủ tục hoạt động trên dữ liệu. Trong lập trình hướng đối tượng, trọng tâm là việc tạo các đối tượng chứa cả dữ liệu và chức năng cùng nhau.objects which contain both data and functionality together.

7.2. Các loại hợp chất do người dùng xác địnhUser-defined compound types¶

Bây giờ chúng tôi sẽ giới thiệu một từ khóa Python mới, lớp, về bản chất xác định một loại dữ liệu mới. Chúng tôi đã sử dụng một số loại tích hợp Python, trong suốt cuốn sách này, giờ đây chúng tôi đã sẵn sàng để tạo loại do người dùng định nghĩa:

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7.class, which in essence defines a new data type. We have been using several of Python’s built-in types throughout this book, we are now ready to create our own user-defined type: the
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7.

Hãy xem xét khái niệm của một điểm toán học. Trong hai chiều, một điểm là hai số [tọa độ] được coi là một đối tượng. Trong ký hiệu toán học, các điểm thường được viết theo dấu ngoặc đơn với dấu phẩy ngăn cách tọa độ. Ví dụ,

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
8 đại diện cho nguồn gốc và
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
9 đại diện cho điểm
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0 đơn vị ở bên phải và
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
1 đơn vị từ gốc.

Một cách tự nhiên để thể hiện một điểm trong Python là với hai giá trị số. Sau đó, câu hỏi là làm thế nào để nhóm hai giá trị này thành một đối tượng ghép. Giải pháp nhanh chóng và bẩn là sử dụng danh sách hoặc tuple, và đối với một số ứng dụng có thể là lựa chọn tốt nhất.

Một giải pháp thay thế là xác định một loại hợp chất do người dùng xác định mới, được gọi là một lớp. Cách tiếp cận này liên quan đến nỗ lực hơn một chút, nhưng nó có những lợi thế sẽ sớm rõ ràng.class. This approach involves a bit more effort, but it has advantages that will be apparent soon.

Một định nghĩa lớp trông như thế này:

Các định nghĩa của lớp có thể xuất hiện ở bất cứ đâu trong một chương trình, nhưng chúng thường ở gần đầu [sau các câu lệnh

print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
2]. Các quy tắc cú pháp cho một định nghĩa lớp giống như đối với các câu lệnh ghép khác. Có một tiêu đề bắt đầu bằng từ khóa,
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
3, theo sau là tên của lớp và kết thúc bằng một dấu hai chấm.

Định nghĩa này tạo ra một lớp mới gọi là

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7. Tuyên bố vượt qua không có hiệu lực; Nó chỉ cần thiết bởi vì một tuyên bố ghép phải có một cái gì đó trong cơ thể của nó. Một tài liệu có thể phục vụ cùng một mục đích:pass statement has no effect; it is only necessary because a compound statement must have something in its body. A docstring could serve the same purpose:

class Point:
    "Point class for storing mathematical points."

Bằng cách tạo lớp

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, chúng tôi đã tạo một loại mới, còn được gọi là
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7. Các thành viên của loại này được gọi là các thể hiện của loại hoặc đối tượng. Tạo một thể hiện mới được gọi là khởi tạo và được thực hiện bằng cách gọi lớp. Các lớp, như các chức năng, có thể gọi được và chúng tôi khởi tạo một đối tượng
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 bằng cách gọi lớp
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7:instances of the type or objects. Creating a new instance is called instantiation, and is accomplished by calling the class. Classes, like functions, are callable, and we instantiate a
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 object by calling the
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 class:

>>> type[Point]

>>> p = Point[]
>>> type[p]

Biến

print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9 được gán một tham chiếu đến một đối tượng
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 mới.

Có thể hữu ích khi nghĩ về một lớp như một nhà máy để tạo ra các đối tượng, vì vậy lớp

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 của chúng tôi là một nhà máy để tạo điểm. Bản thân lớp học không phải là một ví dụ của một điểm, nhưng nó chứa máy móc để thực hiện các trường hợp điểm.

7.3. Thuộc tính¶Attributes¶

Giống như các đối tượng trong thế giới thực, các trường hợp đối tượng có cả hình thức và chức năng. Biểu mẫu bao gồm các yếu tố dữ liệu có trong trường hợp.

Chúng ta có thể thêm các thành phần dữ liệu mới vào một thể hiện bằng ký hiệu DOT:dot notation:

Cú pháp này tương tự như cú pháp để chọn một biến từ một mô -đun, chẳng hạn như

>>> p2 = Point[]
>>> p2.x
Traceback [most recent call last]:
  File "", line 1, in 
AttributeError: 'Point' object has no attribute 'x'
>>>
2 hoặc
>>> p2 = Point[]
>>> p2.x
Traceback [most recent call last]:
  File "", line 1, in 
AttributeError: 'Point' object has no attribute 'x'
>>>
3. Cả hai mô -đun và phiên bản đều tạo ra các không gian tên của riêng chúng và cú pháp để truy cập các tên có trong mỗi tên, được gọi là thuộc tính, là như nhau. Trong trường hợp này, thuộc tính chúng tôi đang chọn là một mục dữ liệu từ một thể hiện.attributes, is the same. In this case the attribute we are selecting is a data item from an instance.

Biểu đồ trạng thái sau đây cho thấy kết quả của các bài tập sau:

Biến

print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9 đề cập đến một đối tượng điểm, chứa hai thuộc tính. Mỗi thuộc tính đề cập đến một số.

Chúng ta có thể đọc giá trị của một thuộc tính bằng cách sử dụng cùng một cú pháp:

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3

Biểu thức

>>> p2 = Point[]
>>> p2.x
Traceback [most recent call last]:
  File "", line 1, in 
AttributeError: 'Point' object has no attribute 'x'
>>>
5 có nghĩa là, Đi đến đối tượng
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9 đề cập đến và nhận giá trị của
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0. Trong trường hợp này, chúng tôi gán giá trị đó cho một biến có tên
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0. Không có xung đột giữa biến
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0 và thuộc tính
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0. Mục đích của ký hiệu DOT là xác định biến nào bạn đang đề cập đến rõ ràng.

Bạn có thể sử dụng ký hiệu DOT như một phần của bất kỳ biểu thức nào, vì vậy các câu sau đây là hợp pháp:

print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y

Dòng đầu ra đầu ra

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
1; Dòng thứ hai tính toán giá trị 25.

7.4. Phương pháp khởi tạo và ________ 82¶The initialization method and
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

Vì lớp

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 của chúng tôi nhằm thể hiện hai điểm toán học hai chiều, tất cả các trường hợp điểm phải có các thuộc tính
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0 và
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
1, nhưng điều đó chưa được như vậy với các đối tượng
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 của chúng tôi.

>>> p2 = Point[]
>>> p2.x
Traceback [most recent call last]:
  File "", line 1, in 
AttributeError: 'Point' object has no attribute 'x'
>>>

Để giải quyết vấn đề này, chúng tôi thêm một phương thức khởi tạo vào lớp của chúng tôi.initialization method to our class.

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

Một phương pháp hoạt động giống như một hàm nhưng nó là một phần của một đối tượng. Giống như một thuộc tính dữ liệu, nó được truy cập bằng ký hiệu DOT.method behaves like a function but it is part of an object. Like a data attribute it is accessed using dot notation.

Phương thức khởi tạo là một phương thức đặc biệt được gọi tự động khi một đối tượng được tạo bằng cách gọi lớp. Tên của phương pháp này là

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
7 [hai ký tự dấu gạch dưới, theo sau là
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
8, và sau đó là hai dấu gạch dưới]. Tên này phải được sử dụng để biến một phương thức thành một phương thức khởi tạo trong Python.

Không có xung đột giữa thuộc tính

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
9 và tham số
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0. Ký hiệu DOT chỉ định biến mà chúng tôi đang đề cập đến.

Hãy để thêm một phương pháp khác,

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
1, để xem cách tốt hơn cách thức hoạt động:

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5

Hãy để tạo ra một vài trường hợp điểm, nhìn vào các thuộc tính của chúng và gọi phương thức mới của chúng tôi trên chúng:

>>> m=fooo[]
>>> m.a
[]
0

Khi xác định một phương thức, tham số đầu tiên đề cập đến thể hiện được tạo. Đó là thông lệ để đặt tên cho tham số này tự. Trong phiên ví dụ ở trên, tham số

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2 đề cập đến các trường hợp
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9,
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
4 và
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
5 tương ứng.self. In the example session above, the
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2 parameter refers to the instances
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9,
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
4, and
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
5 respectively.

7.5. Các thể hiện dưới dạng tham sốInstances as parameters¶

Bạn có thể chuyển một thể hiện dưới dạng tham số cho một hàm theo cách thông thường. Ví dụ:

>>> m=fooo[]
>>> m.a
[]
1

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
6 lấy một điểm làm đối số và hiển thị nó ở định dạng tiêu chuẩn. Nếu bạn gọi
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
7 với điểm
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9 như được định nghĩa trước đó, đầu ra là
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
1.

Để chuyển đổi

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
6 thành phương thức, hãy làm như sau:

  1. Thụt ý định định nghĩa chức năng sao cho nó ở bên trong định nghĩa lớp.

  2. Đổi tên tham số thành

    class Point:
        def __init__[self, x, y]:
            self.x = x
            self.y = y
    
    2.

>>> m=fooo[]
>>> m.a
[]
2

Bây giờ chúng ta có thể gọi phương thức bằng cách sử dụng ký hiệu DOT.

>>> m=fooo[]
>>> m.a
[]
3

Đối tượng mà phương thức được gọi được gán cho tham số đầu tiên, vì vậy trong trường hợp này

print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9 được gán cho tham số
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2. Theo quy ước, tham số đầu tiên của phương thức được gọi là
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2. Lý do cho điều này là một chút phức tạp, nhưng nó dựa trên một phép ẩn dụ hữu ích.

Cú pháp cho một cuộc gọi chức năng,

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
7, cho thấy rằng hàm là tác nhân hoạt động. Nó nói một cái gì đó như, hey
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y

    def distance_from_origin[self]:
        return [[self.x ** 2] + [self.y ** 2]] ** 0.5
6! Ở đây, một đối tượng để bạn in.

Trong lập trình hướng đối tượng, các đối tượng là các tác nhân hoạt động. Một lời cầu khẩn như

>>> m=fooo[]
>>> m.a
[]
07 nói Hey
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
9! Hãy in chính mình!

Sự thay đổi trong quan điểm này có thể lịch sự hơn, nhưng không rõ ràng là nó hữu ích. Trong các ví dụ chúng ta đã thấy cho đến nay, nó có thể không. Nhưng đôi khi chuyển trách nhiệm từ các chức năng vào các đối tượng giúp bạn có thể viết các chức năng linh hoạt hơn và giúp việc duy trì và sử dụng lại mã dễ dàng hơn.

7.6. Các tính năng hướng đối tượngObject-oriented features¶

Không dễ để xác định lập trình hướng đối tượng, nhưng chúng tôi đã thấy một số đặc điểm của nó:

  1. Các chương trình được tạo thành từ các định nghĩa lớp có chứa các thuộc tính có thể là dữ liệu [biến thể hiện] hoặc hành vi [phương thức].

  2. Mỗi định nghĩa đối tượng tương ứng với một số đối tượng hoặc khái niệm trong thế giới thực và các hàm hoạt động trên đối tượng đó tương ứng với các cách các đối tượng trong thế giới thực tương tác.

  3. Hầu hết các tính toán được thể hiện dưới dạng hoạt động trên các đối tượng.

Ví dụ, lớp

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 tương ứng với khái niệm toán học của một điểm.

7.7. Thời gian¶Time¶

Như một ví dụ khác về loại do người dùng xác định, chúng tôi sẽ xác định một lớp gọi là

>>> m=fooo[]
>>> m.a
[]
10 ghi lại thời gian trong ngày. Vì thời gian sẽ cần nhiều giờ, phút và các thuộc tính thứ hai, chúng tôi sẽ bắt đầu với một phương thức khởi tạo tương tự như phương pháp chúng tôi tạo cho các điểm.

Định nghĩa lớp trông như thế này:

>>> m=fooo[]
>>> m.a
[]
4

Khi chúng tôi gọi lớp

>>> m=fooo[]
>>> m.a
[]
10, các đối số chúng tôi cung cấp được chuyển đến
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
8:

>>> m=fooo[]
>>> m.a
[]
5

Dưới đây là phương thức

>>> m=fooo[]
>>> m.a
[]
13 cho các đối tượng
>>> m=fooo[]
>>> m.a
[]
10 của chúng tôi sử dụng chuỗi hình thành để hiển thị phút và giây với hai chữ số.

Để tiết kiệm không gian, chúng tôi sẽ bỏ phương thức khởi tạo, nhưng bạn nên bao gồm nó:

>>> m=fooo[]
>>> m.a
[]
6

mà bây giờ chúng ta có thể gọi các trường hợp theo thời gian theo cách thông thường:

>>> m=fooo[]
>>> m.a
[]
7

7.8. Đối số tùy chọnOptional arguments¶

Chúng tôi đã thấy các chức năng tích hợp có một số lượng đối số khác nhau. Ví dụ,

>>> m=fooo[]
>>> m.a
[]
15 có thể mất hai, ba hoặc bốn đối số.

Có thể viết các chức năng do người dùng xác định với danh sách đối số tùy chọn. Ví dụ: chúng tôi có thể nâng cấp phiên bản

>>> m=fooo[]
>>> m.a
[]
16 của riêng mình để làm điều tương tự như
>>> m=fooo[]
>>> m.a
[]
15.

Đây là phiên bản gốc:

>>> m=fooo[]
>>> m.a
[]
8

Đây là phiên bản mới và được cải tiến:

>>> m=fooo[]
>>> m.a
[]
9

Tham số thứ ba,

>>> m=fooo[]
>>> m.a
[]
18, là tùy chọn vì giá trị mặc định,
>>> m=fooo[]
>>> m.a
[]
19, được cung cấp. Nếu chúng tôi gọi
>>> m=fooo[]
>>> m.a
[]
16 chỉ với hai đối số, chúng tôi sử dụng giá trị mặc định và bắt đầu từ đầu chuỗi:

Nếu chúng tôi cung cấp tham số thứ ba, nó sẽ ghi đè mặc định:overrides the default:

y = fooo[]
y.a = 5
0

Chúng tôi có thể viết lại phương thức khởi tạo của chúng tôi cho lớp

>>> m=fooo[]
>>> m.a
[]
10 để
>>> m=fooo[]
>>> m.a
[]
22,
>>> m=fooo[]
>>> m.a
[]
23 và
>>> m=fooo[]
>>> m.a
[]
24 là mỗi đối số tùy chọn.

y = fooo[]
y.a = 5
1

Khi chúng ta khởi tạo một đối tượng

>>> m=fooo[]
>>> m.a
[]
10, chúng ta có thể truyền các giá trị cho ba tham số, như chúng ta đã làm với

y = fooo[]
y.a = 5
2

Vì các tham số hiện là tùy chọn, tuy nhiên, chúng ta có thể bỏ qua chúng:

y = fooo[]
y.a = 5
3

Hoặc chỉ cung cấp tham số đầu tiên:

y = fooo[]
y.a = 5
4

Hoặc hai tham số đầu tiên:

y = fooo[]
y.a = 5
5

Cuối cùng, chúng tôi có thể cung cấp một tập hợp con của các tham số bằng cách đặt tên chúng một cách rõ ràng:

y = fooo[]
y.a = 5
6

7.9. Một phương pháp khác¶Another method¶

Hãy để thêm một phương thức

>>> m=fooo[]
>>> m.a
[]
26, điều này tăng một thể hiện thời gian theo một số giây nhất định. Để tiết kiệm không gian, chúng tôi sẽ tiếp tục bỏ qua các phương thức được xác định trước đó, nhưng bạn phải luôn giữ chúng trong phiên bản của mình:

y = fooo[]
y.a = 5
7

Bây giờ chúng ta có thể gọi

>>> m=fooo[]
>>> m.a
[]
26 trên một trường hợp thời gian.

y = fooo[]
y.a = 5
8

Một lần nữa, đối tượng mà phương thức được gọi được gán cho tham số đầu tiên,

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2. Tham số thứ hai,
>>> m=fooo[]
>>> m.a
[]
24 nhận được giá trị
>>> m=fooo[]
>>> m.a
[]
30.

7.10. Một ví dụ với hai ____ 110s¶An example with two
>>> m=fooo[]
>>> m.a
[]
10s¶

Hãy để thêm một phương thức Boolen,

>>> m=fooo[]
>>> m.a
[]
32, mất hai trường hợp thời gian và trả về
>>> m=fooo[]
>>> m.a
[]
33 khi phương pháp đầu tiên là theo trình tự thời gian sau lần thứ hai.

Chúng ta chỉ có thể chuyển đổi một trong các tham số thành

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2; cái khác chúng tôi sẽ gọi
>>> m=fooo[]
>>> m.a
[]
35 và nó sẽ phải là một tham số của phương thức.

y = fooo[]
y.a = 5
9

Chúng tôi gọi phương thức này trên một đối tượng và chuyển sang đối tượng khác như một đối số:

class Point:
    "Point class for storing mathematical points."
0

Bạn gần như có thể đọc lời mời như tiếng Anh: Nếu Time1 là sau thời gian2, thì

7.10.1. Các chức năng và sửa đổi thuần túy [một lần nữa]Pure functions and modifiers [again]¶

Trong một vài phần tiếp theo, chúng tôi sẽ viết hai phiên bản của một hàm gọi là

>>> m=fooo[]
>>> m.a
[]
36, tính toán tổng của hai
>>> m=fooo[]
>>> m.a
[]
10s. Họ sẽ chứng minh hai loại chức năng: các chức năng và sửa đổi thuần túy, mà trước tiên chúng tôi gặp phải trong chương chức năng.Functions chapter.

Sau đây là phiên bản sơ bộ của

>>> m=fooo[]
>>> m.a
[]
36:

class Point:
    "Point class for storing mathematical points."
1

Hàm tạo ra một đối tượng

>>> m=fooo[]
>>> m.a
[]
10 mới, khởi tạo các thuộc tính của nó và trả về một tham chiếu đến đối tượng mới. Điều này được gọi là hàm thuần túy vì nó không sửa đổi bất kỳ đối tượng nào được truyền cho nó dưới dạng tham số và nó không có tác dụng phụ, chẳng hạn như hiển thị giá trị hoặc nhận đầu vào của người dùng.pure function because it does not modify any of the objects passed to it as parameters and it has no side effects, such as displaying a value or getting user input.

Dưới đây là một ví dụ về cách sử dụng chức năng này. Chúng tôi sẽ tạo hai đối tượng

>>> m=fooo[]
>>> m.a
[]
10:
>>> m=fooo[]
>>> m.a
[]
41, chứa thời gian hiện tại; và
>>> m=fooo[]
>>> m.a
[]
42, chứa lượng thời gian cần thiết để một thợ làm bánh mì làm bánh mì. Sau đó, chúng tôi sẽ sử dụng
>>> m=fooo[]
>>> m.a
[]
36 để tìm ra khi nào bánh mì sẽ được thực hiện. Nếu bạn đã viết xong
>>> m=fooo[]
>>> m.a
[]
13, hãy nhìn về phía trước trước khi bạn thử điều này:

class Point:
    "Point class for storing mathematical points."
2

Đầu ra của chương trình này là

>>> m=fooo[]
>>> m.a
[]
45, điều này là chính xác. Mặt khác, có những trường hợp kết quả không chính xác. Bạn có thể nghĩ về một?

Vấn đề là chức năng này không giải quyết các trường hợp trong đó số giây hoặc phút tăng lên đến hơn sáu mươi. Khi điều đó xảy ra, chúng ta phải mang thêm giây vào cột phút hoặc thêm phút vào cột giờ.

Ở đây, một phiên bản sửa chữa thứ hai của chức năng:

class Point:
    "Point class for storing mathematical points."
3

Mặc dù chức năng này là chính xác, nó bắt đầu trở nên lớn. Sau đó, chúng tôi sẽ đề xuất một cách tiếp cận thay thế mang lại mã ngắn hơn.

7.10.2. Người sửa đổiModifiers¶

Có những lúc nó hữu ích cho một hàm để sửa đổi một hoặc nhiều đối tượng mà nó nhận được là tham số. Thông thường, người gọi giữ một tham chiếu đến các đối tượng mà nó đi qua, do đó, bất kỳ thay đổi nào mà hàm thực hiện đều có thể nhìn thấy cho người gọi. Các chức năng hoạt động theo cách này được gọi là sửa đổi.modifiers.

>>> m=fooo[]
>>> m.a
[]
26, thêm một số giây nhất định vào đối tượng
>>> m=fooo[]
>>> m.a
[]
10, sẽ được viết một cách tự nhiên nhất là một công cụ sửa đổi. Một bản nháp thô của chức năng trông như thế này:

class Point:
    "Point class for storing mathematical points."
4

Dòng đầu tiên thực hiện hoạt động cơ bản; Phần còn lại liên quan đến các trường hợp đặc biệt mà chúng tôi đã thấy trước đây.

Chức năng này có đúng không? Điều gì xảy ra nếu tham số

>>> m=fooo[]
>>> m.a
[]
24 lớn hơn nhiều so với sáu mươi? Trong trường hợp đó, nó không đủ để mang theo một lần; Chúng ta phải tiếp tục làm điều đó cho đến khi
>>> m=fooo[]
>>> m.a
[]
24 ít hơn sáu mươi. Một giải pháp là thay thế các câu lệnh
>>> m=fooo[]
>>> m.a
[]
50 bằng các câu lệnh
>>> m=fooo[]
>>> m.a
[]
51:

class Point:
    "Point class for storing mathematical points."
5

Hàm này bây giờ là chính xác, nhưng nó không phải là giải pháp hiệu quả nhất.

7.11. Phát triển nguyên mẫu so với kế hoạchPrototype development versus planning¶

Cho đến nay trong chương này, chúng tôi đã sử dụng một cách tiếp cận để phát triển chương trình mà chúng tôi sẽ gọi là phát triển nguyên mẫu. Chúng tôi đã viết một bản nháp thô [hoặc nguyên mẫu] thực hiện tính toán cơ bản và sau đó thử nghiệm nó trên một vài trường hợp, sửa lỗi khi chúng tôi tìm thấy chúng.prototype development. We wrote a rough draft [or prototype] that performed the basic calculation and then tested it on a few cases, correcting flaws as we found them.

Mặc dù cách tiếp cận này có thể có hiệu quả, nhưng nó có thể dẫn đến mã phức tạp không cần thiết - vì nó liên quan đến nhiều trường hợp đặc biệt - và không đáng tin cậy - vì khó có thể biết nếu chúng tôi đã tìm thấy tất cả các lỗi.

Một giải pháp thay thế được lên kế hoạch phát triển, trong đó cái nhìn sâu sắc cấp cao về vấn đề có thể giúp chương trình dễ dàng hơn nhiều. Trong trường hợp này, cái nhìn sâu sắc là một đối tượng

>>> m=fooo[]
>>> m.a
[]
10 thực sự là một số ba chữ số trong cơ sở 60! Thành phần
>>> m=fooo[]
>>> m.a
[]
53 là cột, thành phần
>>> m=fooo[]
>>> m.a
[]
54 là cột sáu mươi và thành phần
>>> m=fooo[]
>>> m.a
[]
55 là cột ba mươi sáu trăm.planned development, in which high-level insight into the problem can make the programming much easier. In this case, the insight is that a
>>> m=fooo[]
>>> m.a
[]
10 object is really a three-digit number in base 60! The
>>> m=fooo[]
>>> m.a
[]
53 component is the ones column, the
>>> m=fooo[]
>>> m.a
[]
54 component is the sixties column, and the
>>> m=fooo[]
>>> m.a
[]
55 component is the thirty-six hundreds column.

Khi chúng tôi viết

>>> m=fooo[]
>>> m.a
[]
36 và
>>> m=fooo[]
>>> m.a
[]
26, chúng tôi đã thực hiện bổ sung trong cơ sở 60, đó là lý do tại sao chúng tôi phải mang từ cột này sang cột tiếp theo.

Quan sát này cho thấy một cách tiếp cận khác cho toàn bộ vấn đề - chúng ta có thể chuyển đổi một đối tượng

>>> m=fooo[]
>>> m.a
[]
10 thành một số duy nhất và tận dụng thực tế là máy tính biết cách thực hiện số học với các số. Hàm sau đây chuyển đổi một đối tượng
>>> m=fooo[]
>>> m.a
[]
10 thành một số nguyên:

class Point:
    "Point class for storing mathematical points."
6

Bây giờ, tất cả những gì chúng ta cần là một cách để chuyển đổi từ một số nguyên sang đối tượng

>>> m=fooo[]
>>> m.a
[]
10:

class Point:
    "Point class for storing mathematical points."
7

Bạn có thể phải suy nghĩ một chút để thuyết phục bản thân rằng kỹ thuật này để chuyển đổi từ cơ sở này sang cơ sở khác là chính xác. Giả sử bạn bị thuyết phục, bạn có thể sử dụng các chức năng này để viết lại

>>> m=fooo[]
>>> m.a
[]
36:

class Point:
    "Point class for storing mathematical points."
8

Phiên bản này ngắn hơn nhiều so với bản gốc và việc chứng minh rằng nó là chính xác hơn nhiều [giả sử, như thường lệ, các chức năng mà nó gọi là chính xác].

7.12. Sự khái quát¶Generalization¶

Trong một số cách, việc chuyển đổi từ cơ sở 60 thành cơ sở 10 và trở lại khó hơn là chỉ xử lý thời gian. Chuyển đổi cơ sở là trừu tượng hơn; Trực giác của chúng tôi để đối phó với thời gian là tốt hơn.

Nhưng nếu chúng ta có cái nhìn sâu sắc để coi thời gian là số 60 và đầu tư viết các chức năng chuyển đổi [

>>> m=fooo[]
>>> m.a
[]
62 và
>>> m=fooo[]
>>> m.a
[]
63], chúng ta sẽ có một chương trình ngắn hơn, dễ đọc và gỡ lỗi hơn và đáng tin cậy hơn.

Nó cũng dễ dàng hơn để thêm các tính năng sau này. Ví dụ, hãy tưởng tượng trừ hai

>>> m=fooo[]
>>> m.a
[]
10 để tìm thời gian giữa chúng. Cách tiếp cận ngây thơ sẽ là thực hiện phép trừ với vay. Sử dụng các chức năng chuyển đổi sẽ dễ dàng hơn và nhiều khả năng là chính xác.

Trớ trêu thay, đôi khi làm cho một vấn đề khó khăn hơn [hoặc tổng quát hơn] làm cho nó dễ dàng hơn [bởi vì có ít trường hợp đặc biệt hơn và ít cơ hội hơn cho lỗi].

7.13. Thuật toánAlgorithms¶

Khi bạn viết một giải pháp chung cho một lớp các vấn đề, trái ngược với một giải pháp cụ thể cho một vấn đề duy nhất, bạn đã viết một thuật toán. Chúng tôi đã đề cập đến từ này trước đây nhưng không định nghĩa nó một cách cẩn thận. Không dễ để xác định, vì vậy chúng tôi sẽ thử một vài cách tiếp cận.algorithm. We mentioned this word before but did not define it carefully. It is not easy to define, so we will try a couple of approaches.

Đầu tiên, hãy xem xét một cái gì đó không phải là một thuật toán. Khi bạn học cách nhân các số một chữ số, có lẽ bạn đã ghi nhớ bảng nhân. Trong thực tế, bạn đã ghi nhớ 100 giải pháp cụ thể. Loại kiến ​​thức đó không phải là thuật toán.

Nhưng nếu bạn lười biếng, có lẽ bạn đã lừa dối bằng cách học một vài thủ thuật. Ví dụ: để tìm sản phẩm của

>>> m=fooo[]
>>> m.a
[]
65 và 9, bạn có thể viết
>>> m=fooo[]
>>> m.a
[]
66 dưới dạng chữ số đầu tiên và
>>> m=fooo[]
>>> m.a
[]
67 là chữ số thứ hai. Thủ thuật này là một giải pháp chung để nhân bất kỳ số một chữ số nào với 9. Đó là một thuật toán!

Tương tự, các kỹ thuật bạn đã học để bổ sung với việc mang theo, trừ với vay và phân chia dài đều là tất cả các thuật toán. Một trong những đặc điểm của thuật toán là chúng không yêu cầu bất kỳ trí thông minh nào để thực hiện. Chúng là các quy trình cơ học trong đó mỗi bước theo sau từ cuối cùng theo một bộ quy tắc đơn giản.

Theo tôi, thật đáng xấu hổ khi con người dành quá nhiều thời gian cho trường học để thực hiện các thuật toán, theo nghĩa đen, không đòi hỏi trí thông minh.

Mặt khác, quá trình thiết kế các thuật toán là thú vị, thách thức trí tuệ và là một phần trung tâm của những gì chúng ta gọi là lập trình.

Một số điều mà mọi người làm một cách tự nhiên, không gặp khó khăn hoặc suy nghĩ có ý thức, là khó nhất để diễn đạt thuật toán. Hiểu ngôn ngữ tự nhiên là một ví dụ tốt. Tất cả chúng ta đều làm điều đó, nhưng cho đến nay không ai có thể giải thích cách chúng ta làm điều đó, ít nhất là không ở dạng thuật toán.

7.14. Điểm được xem xét lạiPoints revisited¶

Hãy để viết lại lớp

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 theo kiểu hướng đối tượng hơn:

class Point:
    "Point class for storing mathematical points."
9

Phương thức tiếp theo,

>>> m=fooo[]
>>> m.a
[]
69, trả về một biểu diễn chuỗi của đối tượng
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7. Nếu một lớp cung cấp một phương thức có tên
>>> m=fooo[]
>>> m.a
[]
69, nó sẽ ghi đè hành vi mặc định của hàm
>>> m=fooo[]
>>> m.a
[]
72 tích hợp Python.

>>> type[Point]

>>> p = Point[]
>>> type[p]

0

In một đối tượng

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 hoàn toàn gọi
>>> m=fooo[]
>>> m.a
[]
69 trên đối tượng, do đó, xác định
>>> m=fooo[]
>>> m.a
[]
69 cũng thay đổi hành vi của
>>> m=fooo[]
>>> m.a
[]
76:

>>> type[Point]

>>> p = Point[]
>>> type[p]

1

Khi chúng tôi viết một lớp mới, chúng tôi hầu như luôn bắt đầu bằng cách viết

class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
7, điều này giúp dễ dàng khởi tạo các đối tượng và
>>> m=fooo[]
>>> m.a
[]
69, hầu như luôn hữu ích cho việc gỡ lỗi.

7.15. Người vận hành quá tảiOperator overloading¶

Một số ngôn ngữ cho phép thay đổi định nghĩa của các toán tử tích hợp khi chúng được áp dụng cho các loại do người dùng xác định. Tính năng này được gọi là quá tải toán tử. Nó đặc biệt hữu ích khi xác định các loại toán học mới.operator overloading. It is especially useful when defining new mathematical types.

Ví dụ: để ghi đè người vận hành bổ sung

>>> m=fooo[]
>>> m.a
[]
79, chúng tôi cung cấp một phương thức có tên
>>> m=fooo[]
>>> m.a
[]
80:

>>> type[Point]

>>> p = Point[]
>>> type[p]

2

Như thường lệ, tham số đầu tiên là đối tượng mà phương thức được gọi. Tham số thứ hai được đặt tên thuận tiện

>>> m=fooo[]
>>> m.a
[]
35 để phân biệt nó với
class Point:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
2. Để thêm hai
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, chúng tôi tạo và trả về một
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 mới chứa tổng tọa độ
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0 và tổng của tọa độ
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
1.

Bây giờ, khi chúng tôi áp dụng toán tử

>>> m=fooo[]
>>> m.a
[]
79 cho các đối tượng
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, Python sẽ gọi
>>> m=fooo[]
>>> m.a
[]
80:

>>> type[Point]

>>> p = Point[]
>>> type[p]

3

Biểu thức

>>> m=fooo[]
>>> m.a
[]
90 tương đương với
>>> m=fooo[]
>>> m.a
[]
91, nhưng rõ ràng thanh lịch hơn. Là một bài tập, thêm một phương thức
>>> m=fooo[]
>>> m.a
[]
92 làm quá tải toán tử trừ và thử nó. Có một số cách để ghi đè hành vi của toán tử nhân: bằng cách xác định một phương thức có tên
>>> m=fooo[]
>>> m.a
[]
93 hoặc
>>> m=fooo[]
>>> m.a
[]
94 hoặc cả hai.

Nếu toán hạng bên trái của

>>> m=fooo[]
>>> m.a
[]
95 là
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, Python sẽ gọi
>>> m=fooo[]
>>> m.a
[]
93, giả định rằng toán hạng khác cũng là một
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7. Nó tính toán sản phẩm DOT của hai điểm, được xác định theo các quy tắc của đại số tuyến tính:dot product of the two points, defined according to the rules of linear algebra:

>>> type[Point]

>>> p = Point[]
>>> type[p]

4

Nếu toán hạng bên trái của

>>> m=fooo[]
>>> m.a
[]
95 là loại nguyên thủy và toán hạng bên phải là
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, Python sẽ gọi
>>> m=fooo[]
>>> m.a
[]
94, thực hiện phép nhân vô hướng:scalar multiplication:

>>> type[Point]

>>> p = Point[]
>>> type[p]

5

Kết quả là một

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 mới có tọa độ là bội số của tọa độ ban đầu. Nếu
>>> m=fooo[]
>>> m.a
[]
35 là loại không thể nhân với số điểm nổi, thì
>>> m=fooo[]
>>> m.a
[]
94 sẽ gây ra lỗi.

Ví dụ này cho thấy cả hai loại nhân:

>>> type[Point]

>>> p = Point[]
>>> type[p]

6

Điều gì xảy ra nếu chúng ta cố gắng đánh giá

y = fooo[]
y.a = 5
05? Vì tham số đầu tiên là
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, Python gọi
>>> m=fooo[]
>>> m.a
[]
93 với
y = fooo[]
y.a = 5
08 làm đối số thứ hai. Bên trong
>>> m=fooo[]
>>> m.a
[]
93, chương trình cố gắng truy cập tọa độ
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0 của
>>> m=fooo[]
>>> m.a
[]
35, không thành công vì số nguyên không có thuộc tính:

>>> type[Point]

>>> p = Point[]
>>> type[p]

7

Thật không may, thông báo lỗi là một chút mờ đục. Ví dụ này cho thấy một số khó khăn của lập trình hướng đối tượng. Đôi khi nó đủ khó chỉ để tìm ra mã nào đang chạy.

Để biết ví dụ đầy đủ hơn về quá tải toán tử, xem Phụ lục [quá tải tham chiếu].

7.16. Sự đa hìnhPolymorphism¶

Hầu hết các phương pháp chúng tôi đã viết chỉ hoạt động cho một loại cụ thể. Khi bạn tạo một đối tượng mới, bạn viết các phương thức hoạt động trên loại đó.

Nhưng có một số hoạt động nhất định mà bạn sẽ muốn áp dụng cho nhiều loại, chẳng hạn như các hoạt động số học trong các phần trước. Nếu nhiều loại hỗ trợ cùng một bộ hoạt động, bạn có thể viết các chức năng hoạt động trên bất kỳ loại nào trong số đó.

Ví dụ: hoạt động

y = fooo[]
y.a = 5
12 [phổ biến trong đại số tuyến tính] có ba tham số; Nó nhân hai đầu tiên và sau đó thêm phần ba. Chúng ta có thể viết nó bằng Python như thế này:

>>> type[Point]

>>> p = Point[]
>>> type[p]

8

Phương pháp này sẽ hoạt động cho bất kỳ giá trị nào của

print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
0 và
print['[{0}, {1}]'.format[p.x, p.y]]
distance_squared = p.x * p.x + p.y * p.y
1 có thể được nhân lên và cho bất kỳ giá trị nào của
y = fooo[]
y.a = 5
15 có thể được thêm vào sản phẩm.

Chúng ta có thể gọi nó với các giá trị số:

Hoặc với

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7S:

>>> type[Point]

>>> p = Point[]
>>> type[p]

9

Trong trường hợp đầu tiên,

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 được nhân với vô hướng và sau đó được thêm vào một
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 khác. Trong trường hợp thứ hai, sản phẩm DOT mang lại giá trị số, do đó tham số thứ ba cũng phải là một giá trị số.

Một chức năng như thế này có thể lấy các tham số với các loại khác nhau được gọi là đa hình.polymorphic.

Một ví dụ khác, hãy xem xét phương pháp

y = fooo[]
y.a = 5
19, in danh sách hai lần, tiến và lùi:

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
0

Vì phương thức

y = fooo[]
y.a = 5
20 là công cụ sửa đổi, chúng tôi tạo một bản sao của danh sách trước khi đảo ngược nó. Bằng cách đó, phương pháp này không sửa đổi danh sách mà nó nhận được dưới dạng tham số.

Ở đây, một ví dụ áp dụng

y = fooo[]
y.a = 5
19 cho danh sách:

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
1

Tất nhiên, chúng tôi dự định áp dụng chức năng này vào danh sách, vì vậy không có gì đáng ngạc nhiên khi nó hoạt động. Điều đáng ngạc nhiên là nếu chúng ta có thể áp dụng nó vào

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7.

Để xác định xem một hàm có thể được áp dụng cho một loại mới hay không, chúng tôi áp dụng quy tắc đa hình cơ bản: nếu tất cả các hoạt động bên trong hàm có thể được áp dụng cho loại, hàm có thể được áp dụng cho loại. Các hoạt động trong phương pháp bao gồm

y = fooo[]
y.a = 5
23,
y = fooo[]
y.a = 5
20 và
>>> m=fooo[]
>>> m.a
[]
76.

y = fooo[]
y.a = 5
23 hoạt động trên bất kỳ đối tượng nào và chúng tôi đã viết một phương thức
>>> m=fooo[]
>>> m.a
[]
69 cho
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7, vì vậy tất cả những gì chúng ta cần là phương thức
y = fooo[]
y.a = 5
20 trong lớp
>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7:

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
2

Sau đó, chúng ta có thể chuyển

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7S đến
y = fooo[]
y.a = 5
19:

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
3

Loại đa hình tốt nhất là loại không chủ ý, nơi bạn phát hiện ra rằng một hàm bạn đã viết có thể được áp dụng cho một loại mà bạn chưa từng lên kế hoạch.

7.17. Bảng chú giải¶Glossary¶

lớp

Một loại hợp chất do người dùng xác định. Một lớp cũng có thể được coi là một mẫu cho các đối tượng là trường hợp của nó.

khởi sự

Để tạo một thể hiện của một lớp.

ví dụ

Một đối tượng thuộc về một lớp.

sự vật

Một loại dữ liệu ghép thường được sử dụng để mô hình hóa một thứ hoặc khái niệm trong thế giới thực.

thuộc tính

Một trong những mục dữ liệu được đặt tên tạo thành một thể hiện.

Chức năng thuần túy

Một hàm không sửa đổi bất kỳ đối tượng nào mà nó nhận được dưới dạng tham số. Hầu hết các chức năng thuần túy đều có kết quả.

bổ nghĩa

Một hàm thay đổi một hoặc nhiều đối tượng mà nó nhận được dưới dạng tham số. Hầu hết các sửa đổi là vô hiệu.

Phong cách lập trình chức năng

Một phong cách thiết kế chương trình trong đó phần lớn các chức năng là thuần túy.

phát triển nguyên mẫu

Một cách phát triển các chương trình bắt đầu với một nguyên mẫu và dần dần kiểm tra và cải thiện nó.

Phát triển theo kế hoạch

Một cách phát triển các chương trình liên quan đến cái nhìn sâu sắc cấp cao về vấn đề và lập kế hoạch nhiều hơn là phát triển gia tăng hoặc phát triển nguyên mẫu.

Ngôn ngữ hướng đối tượng

Một ngôn ngữ cung cấp các tính năng, chẳng hạn như các lớp và kế thừa do người dùng xác định, tạo điều kiện cho lập trình hướng đối tượng.

lập trình hướng đối tượng

Một phong cách lập trình trong đó dữ liệu và các hoạt động thao tác nó được tổ chức thành các lớp và phương pháp.

phương pháp

Một hàm được xác định bên trong định nghĩa lớp và được gọi trên các trường hợp của lớp đó. : Ghi đè :: để thay thế mặc định. Các ví dụ bao gồm thay thế một tham số mặc định bằng một đối số cụ thể và thay thế một phương thức mặc định bằng cách cung cấp một phương thức mới cùng tên.

Phương pháp khởi tạo

Một phương thức đặc biệt được gọi tự động khi một đối tượng mới được tạo và khởi tạo các thuộc tính của đối tượng.

quá tải người vận hành

Mở rộng các toán tử tích hợp [

>>> m=fooo[]
>>> m.a
[]
79,
y = fooo[]
y.a = 5
34,
>>> m=fooo[]
>>> m.a
[]
95,
y = fooo[]
y.a = 5
36,
y = fooo[]
y.a = 5
37, v.v.] để chúng hoạt động với các loại do người dùng xác định.

sản phẩm chấm

Một hoạt động được xác định trong đại số tuyến tính nhân lên hai

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 và mang lại một giá trị số.

nhân bản vô tính

Một hoạt động được xác định trong đại số tuyến tính nhân lên từng tọa độ của

>>> print[p.y]
4
>>> x = p.x
>>> print[x]
3
7 với giá trị số.

đa hình

Một chức năng có thể hoạt động trên nhiều loại. Nếu tất cả các hoạt động trong một hàm có thể được áp dụng cho một loại, thì hàm có thể được áp dụng cho một loại.

Ký hiệu nào được sử dụng để truy cập các thuộc tính đối tượng và lớp trong Python?

getAttr [] - Hàm này được sử dụng để truy cập thuộc tính của đối tượng. HasAttr [] - Hàm này được sử dụng để kiểm tra xem thuộc tính có tồn tại hay không. setAttr [] - Hàm này được sử dụng để đặt thuộc tính. – This function is used to access the attribute of object. hasattr[] – This function is used to check if an attribute exist or not. setattr[] – This function is used to set an attribute.

Ký hiệu nào được sử dụng để truy cập các thuộc tính thể hiện trong Python?

1. Vars [] - Hàm này hiển thị thuộc tính của một thể hiện dưới dạng từ điển.vars[]– This function displays the attribute of an instance in the form of an dictionary.

Đối tượng lớp và thuộc tính trong Python là gì?

Một thuộc tính lớp là một biến thuộc về một lớp nhất định chứ không phải là một đối tượng cụ thể.Mỗi phiên bản của lớp này chia sẻ cùng một biến.Các thuộc tính này thường được xác định bên ngoài hàm tạo __init__.Thuộc tính thể hiện/đối tượng là một biến thuộc về một đối tượng [và chỉ một] đối tượng.. Every instance of this class shares the same variable. These attributes are usually defined outside the __init__ constructor. An instance/object attribute is a variable that belongs to one [and only one] object.

Làm thế nào để bạn truy cập các biến lớp trong Python?

Các biến được xác định bên trong lớp nhưng bên ngoài phương thức có thể được truy cập trong lớp [tất cả các phương thức bao gồm] bằng cách sử dụng thể hiện của một lớp.Ví dụ - bản thân.var_name.Nếu bạn muốn sử dụng biến đó ngay cả bên ngoài lớp, bạn phải khai báo biến đó là toàn cầu.using the instance of a class. For Example – self. var_name. If you want to use that variable even outside the class, you must declared that variable as a global.

Bài Viết Liên Quan

Chủ Đề