Chức năng lớp làm gì trong python?

Chương này được trích từ cuốn sách A Primer on Scientific Programming with Python của H. P. Langtangen, tái bản lần thứ 5, Springer, 2016

Các lớp có thể được sử dụng cho nhiều thứ trong tính toán khoa học, nhưng một trong những nhiệm vụ lập trình thường xuyên nhất là biểu diễn các hàm toán học có một tập tham số ngoài một hoặc nhiều biến độc lập. Mục Thử thách. các hàm có tham số giải thích lý do tại sao các hàm toán học như vậy lại gây khó khăn cho người lập trình và phần Biểu diễn một hàm dưới dạng một lớp cho biết ý tưởng lớp gặp những khó khăn này như thế nào. Các phần Một ví dụ về lớp hàm khác trình bày một ví dụ khác trong đó một lớp biểu diễn một hàm toán học. Tài liệu nâng cao hơn về lớp, mà đối với một số độc giả có thể làm rõ các ý tưởng, nhưng cũng có thể bỏ qua trong lần đọc đầu tiên, xuất hiện trong phần Các triển khai lớp hàm thay thế và phần Tạo lớp không có cấu trúc lớp

Thách đấu. chức năng với các tham số

Để tạo động lực cho khái niệm lớp, chúng ta sẽ xem xét các hàm có tham số. Một ví dụ là \[ y[t]=v_0t-\frac{1}{2}gt^2 \]. Về mặt khái niệm, trong vật lý, đại lượng \[ y \] được xem như một hàm của \[ t \], nhưng \[ y \] còn phụ thuộc vào hai tham số khác là \[ v_0 \] và \[ g \], mặc dù . Chúng ta có thể viết \[ y[t;v_0,g] \] để chỉ ra rằng \[ t \] là biến độc lập, trong khi \[ v_0 \] và \[ g \] là các tham số. Nói đúng ra, \[ g \] là một tham số cố định [miễn là chúng ta ở trên bề mặt trái đất và có thể xem \[ g \] là hằng số], vì vậy chỉ có \[ v_0 \] và \[ t \] mới có thể . Sau đó, sẽ tốt hơn nếu viết \[ y[t;v_0] \]

Trong trường hợp chung, chúng ta có thể có một hàm \[ x \] có \[ n \] tham số \[ p_1,\ldots,p_n \]. \[ f[x; p_1,\ldots,p_n] \]. Một ví dụ có thể là $$ \begin{equation*} g[x; A, a] = Ae^{-ax} \thinspace. \end{phương trình*} $$

Làm thế nào chúng ta nên thực hiện các chức năng như vậy?

def y[t, v0]:
    g = 9.81
    return v0*t - 0.5*g*t**2

def g[x, a, A]:
    return A*exp[-a*x]

Vấn đề

Có một vấn đề lớn với giải pháp này. Nhiều công cụ phần mềm mà chúng ta có thể sử dụng cho các phép toán trên các hàm giả định rằng một hàm của một biến chỉ có một đối số trong biểu diễn hàm của máy tính. Ví dụ: chúng ta có thể có một công cụ để lấy đạo hàm của một hàm \[ f[x] \] tại một điểm \[ x \], sử dụng phép tính gần đúng $$ \begin{equation} f'[x]\approx {f[x

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h

Hàm

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 hoạt động với bất kỳ hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 nào nhận một đối số

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]

Thật không may,

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 sẽ không hoạt động với chức năng
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
4 của chúng tôi. Việc gọi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
5 dẫn đến lỗi bên trong hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1, vì nó cố gọi hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 của chúng ta chỉ với một đối số trong khi hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 yêu cầu hai đối số

Viết một hàm

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 thay thế cho các hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 có hai đối số là một biện pháp khắc phục tồi vì nó hạn chế tập hợp các hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 được chấp nhận trong trường hợp rất đặc biệt của hàm có một biến độc lập và một tham số. Một nguyên tắc cơ bản trong lập trình máy tính là cố gắng tạo ra phần mềm càng phổ biến và có thể áp dụng rộng rãi càng tốt. Trong trường hợp hiện tại, điều đó có nghĩa là hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 phải được áp dụng cho tất cả các hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 của một biến và để
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 nhận một đối số khi đó là quyết định tự nhiên để đưa ra

Sự không phù hợp của các đối số hàm, như đã nêu ở trên, là một vấn đề lớn vì có rất nhiều thư viện phần mềm dành cho các phép toán trên các hàm toán học của một biến. tích phân, vi phân, giải \[ f[x]=0 \], tìm cực trị, v.v. Tất cả các thư viện này sẽ cố gắng gọi hàm toán học mà chúng tôi cung cấp chỉ với một đối số. Khi chức năng của chúng tôi có nhiều đối số hơn, mã bên trong thư viện sẽ hủy bỏ lệnh gọi đến chức năng của chúng tôi và các lỗi như vậy có thể không phải lúc nào cũng dễ dàng theo dõi

Một giải pháp tồi. biến toàn cầu

Do đó, yêu cầu là xác định các triển khai Python của các hàm toán học của một biến với một đối số, biến độc lập. Hai ví dụ trên sau đó phải được thực hiện như

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
7

Các hàm này chỉ hoạt động nếu

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
86 và
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
87 là các biến toàn cục, được khởi tạo trước khi một người cố gắng gọi hàm. Dưới đây là hai cuộc gọi mẫu trong đó
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1 phân biệt giữa
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]

Việc sử dụng các biến toàn cục nói chung được coi là lập trình tồi. Tại sao các biến toàn cục lại có vấn đề trong trường hợp hiện tại có thể được minh họa khi cần phải làm việc với một số phiên bản của hàm. Giả sử chúng ta muốn làm việc với hai phiên bản của \[ y[t;v_0] \], một với \[ v_0=1 \] và một với \[ v_0=5 \]. Mỗi khi chúng ta gọi

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, chúng ta phải nhớ phiên bản nào của chức năng mà chúng ta làm việc và đặt
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 tương ứng trước khi gọi

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
8

Một vấn đề khác là các biến có tên đơn giản như

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
87 và
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
86 có thể dễ dàng được sử dụng làm biến toàn cục trong các phần khác của chương trình. Những phần này có thể thay đổi
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 của chúng tôi trong ngữ cảnh khác với chức năng
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, nhưng sự thay đổi đó ảnh hưởng đến tính chính xác của chức năng
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Trong trường hợp như vậy, chúng tôi nói rằng việc thay đổi
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 có tác dụng phụ, tôi. e. , sự thay đổi ảnh hưởng đến các phần khác của chương trình một cách không chủ ý. Đây là một lý do tại sao quy tắc vàng trong lập trình yêu cầu chúng ta hạn chế sử dụng các biến toàn cục càng nhiều càng tốt

Một giải pháp khác cho vấn đề cần hai tham số \[ v_0 \] có thể là giới thiệu hai hàm

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, mỗi hàm có một tham số \[ v_0 \] riêng biệt

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
3

Bây giờ chúng ta cần khởi tạo

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
71 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
72 một lần, sau đó chúng ta có thể làm việc với
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
73 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
74. Tuy nhiên, nếu chúng ta cần 100 tham số \[ v_0 \] thì chúng ta cần 100 hàm. Điều này gây tẻ nhạt cho mã, dễ xảy ra lỗi, khó quản trị và đơn giản là một giải pháp thực sự tồi tệ cho một vấn đề lập trình

Vì vậy, có một biện pháp khắc phục tốt? . khái niệm lớp giải quyết tất cả các vấn đề được mô tả ở trên

Biểu diễn một hàm dưới dạng một lớp

Một lớp chứa một tập hợp các biến [dữ liệu] và một tập hợp các hàm, được tổ chức cùng nhau dưới dạng một đơn vị. Các biến có thể nhìn thấy trong tất cả các chức năng trong lớp. Tức là chúng ta có thể xem các biến là "toàn cục" trong các hàm này. Những đặc điểm này cũng áp dụng cho các mô-đun và các mô-đun có thể được sử dụng để đạt được nhiều lợi ích giống như các lớp mang lại [xem nhận xét trong phần Tạo lớp không có cấu trúc lớp]. Tuy nhiên, các lớp về mặt kỹ thuật rất khác so với các mô-đun. Bạn cũng có thể tạo nhiều bản sao của một lớp, trong khi chỉ có thể có một bản sao của một mô-đun. Khi bạn thành thạo cả module và class, bạn sẽ thấy rõ sự giống và khác nhau. Bây giờ chúng ta tiếp tục với một ví dụ cụ thể về một lớp

Xét hàm \[ y[t; v_0]=v_0t - \frac{1}{2}gt^2 \]. Chúng ta có thể nói rằng \[ v_0 \] và \[ g \], được đại diện bởi các biến

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30, cấu thành dữ liệu. Cần có một hàm Python, chẳng hạn như
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
77, để tính giá trị của \[ y[t;v_0] \] và hàm này phải có quyền truy cập vào dữ liệu
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30, trong khi
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
60 là một đối số

Sau đó, một lập trình viên có kinh nghiệm với các lớp sẽ đề xuất thu thập dữ liệu

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30, và hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
77, cùng nhau dưới dạng một lớp. Ngoài ra, một lớp thường có một chức năng khác, được gọi là hàm khởi tạo để khởi tạo dữ liệu. Hàm tạo luôn có tên là
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64. Mỗi lớp phải có một tên, thường bắt đầu bằng chữ hoa, vì vậy chúng tôi chọn
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 làm tên vì lớp đại diện cho một hàm toán học có tên \[ y \]. Hình 1 phác thảo nội dung của lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 dưới dạng cái gọi là sơ đồ UML, ở đây được tạo ra với sự trợ giúp của chương trình class_Y_v1_UML. py. Sơ đồ UML có hai "hộp", một nơi liệt kê các chức năng và một nơi liệt kê các biến. Bước tiếp theo của chúng tôi là triển khai lớp này bằng Python

Hình 1. Sơ đồ UML với chức năng và dữ liệu trong lớp đơn giản

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 để biểu diễn một hàm toán học \[ y[t;v_0] \]

Thực hiện

Mã hoàn chỉnh cho lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 của chúng tôi trông như sau trong Python

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7

Một điều khó hiểu đối với những người mới tham gia các lớp Python là tham số

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69, có thể mất một số nỗ lực và thời gian để hiểu đầy đủ

Sử dụng và mổ xẻ

Trước khi tìm hiểu ý nghĩa của từng dòng trong phần triển khai lớp, chúng ta bắt đầu bằng cách chỉ ra cách lớp có thể được sử dụng để tính toán các giá trị của hàm toán học \[ y[t;v_0] \]

Một lớp tạo ra một kiểu dữ liệu mới, ở đây có tên là

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65, vì vậy khi chúng ta sử dụng lớp để tạo các đối tượng thì các đối tượng đó thuộc kiểu
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. [Trên thực tế, tất cả các đối tượng Python tiêu chuẩn, chẳng hạn như danh sách, bộ dữ liệu, chuỗi, số dấu phẩy động, số nguyên, v.v. , là các lớp Python tích hợp, với các tên
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
92,
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
93,
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
94,
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
95,
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
96, v.v. ] Một đối tượng của lớp do người dùng định nghĩa [như
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65] thường được gọi là một thể hiện. Chúng ta cần một thể hiện như vậy để sử dụng dữ liệu trong lớp và gọi hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98. Câu lệnh sau xây dựng một thể hiện được liên kết với tên biến
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7

Dường như, chúng ta gọi lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 như thể nó là một hàm. Trên thực tế,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
01 được Python dịch tự động thành lệnh gọi hàm tạo
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64 trong lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. Các đối số trong cuộc gọi, ở đây chỉ có số
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04, luôn được chuyển thành đối số cho
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64 sau đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69. Nghĩa là,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 nhận giá trị
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 vừa bị loại bỏ trong cuộc gọi. Điều này có thể gây nhầm lẫn, nhưng có một quy tắc là đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 không bao giờ được sử dụng trong các lệnh gọi hàm trong lớp

Với ví dụ

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, chúng ta có thể tính giá trị \[ y[t=0. 1;v_0=3] \] bởi câu lệnh

Ở đây cũng vậy, đối số

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 bị loại bỏ trong lệnh gọi tới
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98. Để truy cập các hàm và biến trong một lớp, chúng ta phải thêm tiền tố vào tên hàm và biến bằng tên của thể hiện và dấu chấm. hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 đạt được là
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
15 và các biến đạt được là
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
16 và
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
17. Ví dụ, chúng ta có thể in ra giá trị của
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 trong trường hợp
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 bằng cách viết

Đầu ra trong trường hợp này sẽ là

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04

Chúng tôi đã giới thiệu thuật ngữ "thể hiện" cho đối tượng của một lớp. Các hàm trong các lớp thường được gọi là các phương thức và các biến [dữ liệu] trong các lớp được gọi là các thuộc tính dữ liệu. Các phương thức còn được gọi là các thuộc tính của phương thức. Từ bây giờ chúng ta sẽ sử dụng thuật ngữ này. Trong lớp mẫu

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 của chúng ta, chúng ta có hai phương thức hoặc thuộc tính phương thức,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98, hai thuộc tính dữ liệu,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30, và tổng cộng bốn thuộc tính [
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64,
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30]. Tên của các thuộc tính có thể được chọn tự do, giống như tên của các hàm và biến Python thông thường. Tuy nhiên constructor phải có tên là
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64, nếu không nó sẽ không tự động được gọi khi chúng ta tạo instance mới

Bạn có thể làm bất cứ điều gì bạn muốn trong bất kỳ phương thức nào, nhưng quy ước chung là sử dụng hàm tạo để khởi tạo các biến trong lớp

Gia hạn lớp học

Chúng ta có thể có bao nhiêu thuộc tính tùy thích trong một lớp, vì vậy hãy thêm một phương thức mới vào lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. Phương thức này được gọi là
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
32 và in ra một chuỗi chứa công thức của hàm toán học \[ y \]. Sau công thức này, chúng tôi cung cấp giá trị của \[ v_0 \]. Chuỗi sau đó có thể được xây dựng như

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
6

trong đó

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 là một thể hiện của lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. Cuộc gọi của
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
32 không cần bất kỳ đối số nào

phải đủ để tạo, trả về và in chuỗi. Tuy nhiên, ngay cả khi phương thức

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
32 không cần bất kỳ đối số nào, thì nó phải có đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69, đối số này bị bỏ qua trong lệnh gọi nhưng cần thiết bên trong phương thức để truy cập các thuộc tính. Do đó, việc thực hiện phương pháp

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
9

Cho đầy đủ, bây giờ cả lớp đọc

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
0

Ví dụ về sử dụng có thể là

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
1

với đầu ra

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
2

Hãy cẩn thận với thụt đầu dòng trong lập trình lớp. Một sai lầm phổ biến của những người mới bắt đầu xây dựng lớp là đặt mã áp dụng lớp ở cùng một khoảng thụt đầu dòng như các phương thức của lớp. điều này là bất hợp pháp. Chỉ các định nghĩa phương thức và phép gán cho cái gọi là thuộc tính dữ liệu tĩnh [phần Phương thức và thuộc tính tĩnh] mới có thể xuất hiện trong khối thụt lề bên dưới tiêu đề

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
38. Việc gán thuộc tính dữ liệu thông thường phải được thực hiện bên trong các phương thức. Chương trình chính sử dụng lớp phải xuất hiện với cùng thụt lề như dòng tiêu đề
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
38

Sử dụng các phương thức như các hàm thông thường

Chúng tôi có thể tạo một số hàm \[ y \] với các giá trị khác nhau của \[ v_0 \]

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
3

Chúng ta có thể coi

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
40,
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
41 và
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
42 là các hàm Python thông thường của
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
60, sau đó chuyển chúng cho bất kỳ hàm Python nào mong đợi hàm một biến. Cụ thể, chúng ta có thể gửi các hàm tới hàm
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
44 từ phần Thử thách. chức năng với các tham số

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
4

Bên trong hàm

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
44, đối số
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 hiện hoạt động như một hàm của một biến tự động mang theo hai biến
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30. Khi
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
2 đề cập đến [e. g. ]
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
42, Python thực sự biết rằng
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
51 có nghĩa là
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
52, và bên trong phương thức
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
42,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 là
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
55, và chúng ta có quyền truy cập vào
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
56 và
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
57

Lớp học kiểu mới so với lớp học cổ điển

Khi sử dụng Python phiên bản 2 và viết một lớp như

chúng tôi nhận được những gì được gọi là một lớp kiểu cũ hoặc cổ điển. Việc triển khai sửa đổi các lớp trong Python đã có trong phiên bản 2. 2 với các lớp học kiểu mới. Đặc điểm kỹ thuật của một lớp kiểu mới yêu cầu

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
58 sau tên lớp

Các lớp kiểu mới có nhiều chức năng hơn và nói chung nên làm việc với các lớp kiểu mới. Do đó, từ bây giờ chúng ta sẽ viết

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
59 thay vì chỉ viết
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
60. Trong Python 3, tất cả các lớp đều là kiểu mới cho dù chúng ta viết
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
60 hay
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
59

chuỗi tài liệu

Một hàm có thể có một chuỗi tài liệu ngay sau định nghĩa hàm, xem phần ref{sec. nền tảng. chuỗi tài liệu}. Mục đích của chuỗi tài liệu là để giải thích mục đích của hàm và, ví dụ, đối số và giá trị trả về là gì. Một lớp cũng có thể có một chuỗi tài liệu, nó chỉ là chuỗi đầu tiên xuất hiện ngay sau tiêu đề

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
38. Quy ước là đặt chuỗi tài liệu trong ba dấu ngoặc kép
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
64

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
5

Thông tin toàn diện hơn có thể bao gồm các phương pháp và cách lớp được sử dụng trong phiên tương tác

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
6

biến tự

Bây giờ chúng ta sẽ giải thích thêm về tham số

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 và cách hoạt động của các phương thức lớp. Bên trong hàm tạo
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
64, đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 là một biến chứa thể hiện mới sẽ được tạo. Khi chúng ta viết

chúng tôi xác định hai thuộc tính dữ liệu mới trong trường hợp này. Tham số

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 được trả về mã gọi một cách vô hình. Chúng ta có thể tưởng tượng rằng Python dịch cú pháp
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
69 thành lời gọi được viết là

Bây giờ,

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 trở thành phiên bản mới
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 mà chúng tôi muốn tạo, vì vậy khi chúng tôi thực hiện
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
72 trong hàm tạo, chúng tôi thực sự gán
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 cho
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
16. Tiền tố với
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
75 minh họa cách tiếp cận một phương thức lớp với cú pháp tương tự như cách tiếp cận một hàm trong mô-đun [giống như
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
76]. Nếu chúng ta đặt tiền tố bằng
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
75, chúng ta cần cung cấp rõ ràng một thực thể cho đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69, chẳng hạn như
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 trong dòng mã ở trên, nhưng nếu chúng ta thêm tiền tố bằng
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
80 [tên thực thể] thì đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 sẽ bị loại bỏ trong cú pháp và Python sẽ . Đây là "tiền tố tên đối tượng" mà chúng ta sẽ sử dụng khi tính toán với các lớp. [
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
84 sẽ không hoạt động vì
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 không được xác định và được cho là một đối tượng
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. Tuy nhiên, nếu trước tiên chúng tôi tạo
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
87 và sau đó gọi
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
84, cú pháp sẽ hoạt động và
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
16 là
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
04 sau cuộc gọi. ]

Chúng ta hãy xem một cuộc gọi đến phương thức

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 để xem cách sử dụng tương tự đối số
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69. Khi chúng ta viết

Python dịch điều này thành một cuộc gọi

sao cho đối số

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 trong phương thức
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 trở thành đối tượng
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Trong biểu thức bên trong phương thức
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98,

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
7

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 là
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 vì vậy điều này giống như

Việc sử dụng

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 có thể trở nên rõ ràng hơn khi chúng ta có nhiều thể hiện lớp. Chúng ta có thể tạo một lớp chỉ có một tham số để chúng ta có thể dễ dàng xác định một thể hiện của lớp bằng cách in giá trị của tham số này. Ngoài ra, mọi đối tượng Python
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
00 đều có một mã định danh duy nhất do
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
01 thu được mà chúng ta cũng có thể in ra để theo dõi xem
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 là gì

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
8

Đây là một phiên tương tác với lớp học này

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
9

Chúng ta thấy rõ ràng rằng

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 bên trong hàm tạo là cùng một đối tượng như
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
04 mà chúng ta muốn tạo bằng cách gọi hàm tạo

Một đối tượng thứ hai được thực hiện bởi

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
0

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

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 bằng cách sử dụng cú pháp tiêu chuẩn
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
06 và cú pháp "mô phạm hơn"
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
07. Sử dụng cả
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
04 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
09 minh họa cách
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 nhận các giá trị khác nhau, trong khi chúng ta có thể xem phương thức
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
11 như một hàm duy nhất chỉ hoạt động trên các đối tượng
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
13 khác nhau

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
1

Hy vọng rằng những minh họa này giúp giải thích rằng

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 chỉ là ví dụ được sử dụng trong tiền tố gọi phương thức, ở đây là
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
04 hoặc
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
09. Nếu không, kiên nhẫn làm việc với lập trình lớp trong Python theo thời gian sẽ tiết lộ sự hiểu biết về những gì
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 thực sự là

Các quy tắc liên quan đến

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69
  • Bất kỳ phương thức lớp nào cũng phải có
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    69 làm đối số đầu tiên. [Tên có thể là bất kỳ tên biến hợp lệ nào, nhưng tên
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    69 là một quy ước được thiết lập rộng rãi trong Python. ]
  • def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    69 đại diện cho một thể hiện [tùy ý] của lớp
  • Để truy cập bất kỳ thuộc tính lớp nào bên trong các phương thức lớp, chúng ta phải đặt tiền tố bằng
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    69, như trong
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    23, trong đó
    def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    24 là tên của thuộc tính
  • def h[t]:
        return t**4 + 4*t
    
    dh = diff[h, 0.1]
    
    from math import sin, pi
    x = 2*pi
    dsin = diff[sin, x, h=1E-6]
    
    69 bị loại bỏ dưới dạng đối số trong các cuộc gọi đến các phương thức lớp

Một ví dụ lớp chức năng khác

Chúng ta hãy áp dụng ý tưởng từ lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 cho hàm $$ \begin{equation*} v[r] = \left[{\beta\over 2\mu_0}\right]^{{1/ n}} {n . Chúng ta có thể viết hàm này là \[ v[r; \beta,\mu_0,n,R] \] để biểu thị rõ ràng rằng có một biến độc lập chính [\[ r \]] và bốn tham số vật lý \[ \beta \ . Lớp này thường giữ các tham số vật lý dưới dạng biến và cung cấp phương thức
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
27 để tính toán hàm \[ v \]

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
2

Có vẻ như có một điều mới ở đây là chúng ta khởi tạo một số biến trên cùng một dòng

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
3

Danh sách các biến được phân tách bằng dấu phẩy ở phía bên tay phải tạo thành một bộ vì vậy phép gán này chỉ là một cấu trúc hợp lệ trong đó một tập hợp các biến ở phía bên trái được đặt bằng một danh sách hoặc bộ ở phía bên tay phải . Một mã nhiều dòng tương đương là

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
4

Trong phương pháp

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98, thật thuận tiện để tránh tiền tố
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
29 trong các công thức toán học và thay vào đó giới thiệu các tên viết tắt địa phương
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
30,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
31,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
32 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
33. Nói chung, đây là một ý tưởng hay, vì nó giúp dễ dàng đọc cách thực hiện công thức và kiểm tra tính đúng đắn của nó

Nhận xét

Một giải pháp khác cho vấn đề gửi các hàm có tham số đến một hàm thư viện chung, chẳng hạn như

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1, được cung cấp trong tài liệu Biến số đối số của hàm trong Python [2]. Biện pháp khắc phục là chuyển các tham số dưới dạng đối số "thông qua" hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
1. Điều này có thể được thực hiện một cách tổng quát như được giải thích trong phụ lục đó

Triển khai lớp chức năng thay thế

Để minh họa thêm về lập trình lớp, bây giờ chúng ta sẽ nhận ra lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 từ phần Biểu diễn một hàm dưới dạng một lớp theo một cách khác. Bạn có thể coi phần này là phần nâng cao và bỏ qua nó, nhưng đối với một số độc giả, tài liệu này có thể cải thiện sự hiểu biết về lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 và cung cấp một số hiểu biết sâu sắc về lập trình lớp nói chung

Một thói quen tốt là luôn có một hàm tạo trong một lớp và khởi tạo các thuộc tính dữ liệu trong lớp ở đây, nhưng đây không phải là một yêu cầu. Hãy để chúng tôi loại bỏ hàm tạo và biến

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 thành một đối số tùy chọn cho phương thức
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98. Nếu người dùng không cung cấp
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 trong cuộc gọi tới
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98, chúng tôi sẽ sử dụng giá trị
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 phải được cung cấp trong cuộc gọi trước đó và được lưu trữ dưới dạng thuộc tính dữ liệu
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43. Chúng ta có thể nhận ra liệu người dùng có cung cấp _____185 làm đối số hay không bằng cách sử dụng _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mẽ

Việc triển khai thay thế của lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65, được đặt tên là
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48, hiện đã đọc

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
5

Lần này, lớp chỉ có một phương thức và một thuộc tính dữ liệu vì chúng ta đã bỏ qua hàm tạo và để

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30 là một biến cục bộ trong phương thức
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98

Nhưng nếu không có hàm tạo, thì một thể hiện được tạo như thế nào? . Điều này cho phép chúng tôi viết

để làm một ví dụ

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Vì không có gì xảy ra trong hàm tạo trống được tạo tự động, nên
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 không có thuộc tính dữ liệu nào ở giai đoạn này. Viết

do đó dẫn đến ngoại lệ

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
6

Bằng cách gọi

chúng tôi tạo một thuộc tính

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 bên trong phương thức
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98. Nói chung, chúng ta có thể tạo bất kỳ thuộc tính
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
24 nào trong bất kỳ phương thức nào bằng cách chỉ gán một giá trị cho
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
23. Bây giờ đang thử một

sẽ in

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
57. Trong một cuộc gọi mới,

giá trị

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 trước đó [
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
57] được sử dụng bên trong
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 là
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 trừ khi đối số
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 được chỉ định trong cuộc gọi

Việc triển khai trước đó không thể đánh lừa được nếu chúng tôi không khởi tạo được

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85. Ví dụ, mã

sẽ chấm dứt trong phương pháp

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 với ngoại lệ

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
6

Như thường lệ, tốt hơn là thông báo cho người dùng bằng một thông báo nhiều thông tin hơn. Để kiểm tra xem chúng ta có thuộc tính

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 hay không, chúng ta có thể sử dụng hàm Python
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
66. Gọi
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
67 chỉ trả về
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
68 nếu thể hiện
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 có một thuộc tính có tên
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
70. Một phương pháp
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 được cải tiến hiện đọc

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
8

Ngoài ra, chúng ta có thể thử truy cập

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 trong một khối
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
73 và có thể đưa ra một ngoại lệ
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
74 [đây là điều mà Python đưa ra nếu không có đủ đối số cho một hàm hoặc phương thức]

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
9

Lưu ý rằng Python phát hiện một

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
75, nhưng theo quan điểm của người dùng, không có đủ tham số được cung cấp trong cuộc gọi nên một
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
74 phù hợp hơn để liên lạc lại với mã cuộc gọi

Chúng tôi nghĩ lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 triển khai tốt hơn lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48, vì lớp trước đơn giản hơn. Như đã đề cập, thói quen tốt là bao gồm một hàm tạo và đặt dữ liệu ở đây thay vì "ghi dữ liệu một cách nhanh chóng" như chúng ta cố gắng thực hiện trong lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48. Toàn bộ mục đích của lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
48 chỉ là để chỉ ra rằng Python cung cấp tính linh hoạt cao đối với việc xác định các thuộc tính và không có yêu cầu nào đối với những gì một lớp phải chứa

Tạo các lớp không có cấu trúc lớp

Những người mới làm quen với khái niệm lớp học thường gặp khó khăn để hiểu khái niệm này là gì. Phần hiện tại cố gắng giải thích chi tiết hơn về cách chúng ta có thể giới thiệu các lớp mà không cần cấu trúc lớp bằng ngôn ngữ máy tính. Thông tin này có thể hoặc không thể làm tăng sự hiểu biết của bạn về các lớp học. Nếu không, lập trình với các lớp chắc chắn sẽ nâng cao hiểu biết của bạn theo thời gian, vì vậy không có lý do gì phải lo lắng. Trên thực tế, bạn có thể chuyển sang phần Phương pháp đặc biệt một cách an toàn vì không có khái niệm quan trọng nào trong phần này mà các phần sau sẽ dựa vào

Một lớp chứa tập hợp các biến [dữ liệu] và tập hợp các phương thức [hàm]. Tập hợp các biến là duy nhất cho mỗi thể hiện của lớp. Nghĩa là, nếu chúng ta tạo 10 trường hợp, thì mỗi trường hợp có một tập biến riêng. Các biến này có thể được coi như một từ điển với các khóa bằng tên biến. Sau đó, mỗi phiên bản có từ điển riêng và chúng ta có thể xem đại khái phiên bản đó là từ điển này. [Thể hiện cũng có thể chứa các thuộc tính dữ liệu tĩnh [phần Các phương thức và thuộc tính tĩnh], nhưng chúng được xem như các biến toàn cục trong bối cảnh hiện tại. ]

Mặt khác, các phương thức được chia sẻ giữa các thể hiện. Chúng ta có thể coi một phương thức trong một lớp là một hàm toàn cục tiêu chuẩn lấy một thể hiện ở dạng từ điển làm đối số đầu tiên. Sau đó, phương thức này có quyền truy cập vào các biến trong thể hiện [từ điển] được cung cấp trong cuộc gọi. Đối với lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 từ phần Biểu diễn một hàm dưới dạng một lớp và một thể hiện
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, các phương thức là các hàm thông thường với các tên và đối số sau

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
70

Lớp hoạt động như một không gian tên, nghĩa là tất cả các chức năng phải được thêm tiền tố bởi tên không gian tên, ở đây

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. Hai lớp khác nhau, chẳng hạn như
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
84 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
85, có thể có các hàm có cùng tên, chẳng hạn như
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98, nhưng khi các hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
98 thuộc về các không gian tên khác nhau, tên của chúng
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
88 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
89 trở nên khác biệt. Các mô-đun cũng là không gian tên cho các hàm và biến trong chúng [nghĩ về
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
90,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
91,
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
92]

Điều đặc biệt duy nhất với cấu trúc lớp trong Python là nó cho phép chúng ta sử dụng một cú pháp thay thế cho các lệnh gọi phương thức

Cú pháp này trùng với cú pháp truyền thống gọi các phương thức lớp và cung cấp đối số, như được tìm thấy trong các ngôn ngữ máy tính khác, chẳng hạn như Java, C#, C++, Simula và Smalltalk. Ký hiệu dấu chấm cũng được sử dụng để truy cập các biến trong một thể hiện sao cho chúng ta bên trong một phương thức có thể viết

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
43 thay vì
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
94 [
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
69 đề cập đến
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 thông qua lệnh gọi hàm]

Chúng ta có thể dễ dàng triển khai một phiên bản đơn giản của khái niệm lớp mà không cần xây dựng lớp bằng ngôn ngữ. Tất cả những gì chúng ta cần là một loại từ điển và các chức năng thông thường. Từ điển đóng vai trò là thể hiện và các phương thức là các hàm lấy từ điển này làm đối số đầu tiên sao cho hàm có quyền truy cập vào tất cả các biến trong thể hiện. Lớp

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65 của chúng tôi bây giờ có thể được thực hiện như

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
71

Hai chức năng được đặt trong một mô-đun có tên là

def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65. Việc sử dụng diễn ra như sau

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
72

Chúng tôi không có hàm tạo vì việc khởi tạo các biến được thực hiện khi khai báo từ điển

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7, nhưng chúng tôi cũng có thể đưa một số hàm khởi tạo vào mô-đun
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
73

Cách sử dụng bây giờ hơi khác một chút

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
74

Cách triển khai lớp này với sự trợ giúp của từ điển và một tập hợp các hàm thông thường thực sự tạo cơ sở cho việc triển khai lớp trong nhiều ngôn ngữ. Python và Perl thậm chí còn có cú pháp thể hiện kiểu triển khai này. Trên thực tế, mọi thể hiện của lớp trong Python đều có một từ điển

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
701 làm thuộc tính, chứa tất cả các biến trong thể hiện. Đây là bản demo chứng minh sự tồn tại của từ điển này trong lớp
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
65

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
75

Để tóm tắt. Một lớp Python có thể được coi là một số biến được thu thập trong từ điển và một tập hợp các hàm trong đó từ điển này được cung cấp tự động làm đối số đầu tiên sao cho các hàm luôn có quyền truy cập đầy đủ vào các biến của lớp

nhận xét đầu tiên

Trong phần này, chúng tôi đã cung cấp chế độ xem các lớp từ quan điểm kỹ thuật. Những người khác có thể xem một lớp như một cách mô hình hóa thế giới về mặt dữ liệu và hoạt động trên dữ liệu. Tuy nhiên, trong các ngành khoa học sử dụng ngôn ngữ toán học, việc mô hình hóa thế giới thường được thực hiện bằng toán học và các cấu trúc toán học cung cấp sự hiểu biết về vấn đề và cấu trúc của các chương trình. Khi thích hợp, cấu trúc toán học có thể được ánh xạ thuận tiện vào các lớp trong chương trình để làm cho phần mềm đơn giản và linh hoạt hơn

nhận xét thứ hai

Khung nhìn của các lớp trong phần này bỏ qua các chủ đề rất quan trọng như kế thừa và liên kết động [được giải thích trong tài liệu Lập trình hướng đối tượng [1]]. Để phần hiện tại đầy đủ hơn, do đó, chúng tôi mô tả ngắn gọn cách kết hợp từ điển và các hàm toàn cục của chúng tôi có thể xử lý tính kế thừa và liên kết động [nhưng điều này sẽ không có ý nghĩa trừ khi bạn biết tính kế thừa là gì]

Kế thừa dữ liệu có thể thu được bằng cách cho phép từ điển lớp con thực hiện cuộc gọi

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
703 với từ điển lớp cha làm đối số. Theo cách này, tất cả dữ liệu trong lớp cha cũng có sẵn trong từ điển lớp con. Liên kết động của các phương thức phức tạp hơn, nhưng người ta có thể nghĩ đến việc kiểm tra xem phương thức đó có nằm trong mô-đun lớp con hay không [sử dụng
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
66] và nếu không, người ta tiếp tục kiểm tra các mô-đun siêu hạng cho đến khi tìm thấy phiên bản của phương thức

đóng cửa

Phần này nối tiếp cuộc thảo luận trong phần Tạo lớp không có cấu trúc lớp và trình bày một cấu trúc nâng cao hơn có thể đóng vai trò thay thế cho cấu trúc lớp trong một số trường hợp

Ví dụ thúc đẩy của chúng tôi là chúng tôi muốn Python triển khai hàm toán học \[ y[t;v_0]=v_0t - \frac{1}{2}gt^2 \] có \[ t \] làm đối số duy nhất, . Hãy xem xét hàm sau, trả về một hàm

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
76

Thuộc tính đáng chú ý của hàm

v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7 là nó ghi nhớ giá trị của
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
30, mặc dù các biến này không cục bộ đối với hàm mẹ
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
708 và không cục bộ trong
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7. Đặc biệt, chúng ta có thể chỉ định
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 làm đối số cho
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
708

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
77

Ở đây,

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
712 có quyền truy cập vào
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
713 trong khi
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
714 có quyền truy cập vào
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
715

Hàm

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
716 chúng ta xây dựng và trả về từ
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
708 được gọi là một bao đóng và nó ghi nhớ giá trị của các biến cục bộ xung quanh trong hàm cha [tại thời điểm chúng ta tạo hàm
v0 = 3
dy = diff[y, 1]

A = 1; a = 0.1
dg = diff[g, 1.5]
7]. Bao đóng rất thuận tiện cho nhiều mục đích trong tính toán toán học. Các ví dụ xuất hiện trong phần Ví dụ. Tự động phân biệt. Bao đóng cũng là trung tâm trong phong cách lập trình được gọi là lập trình chức năng

Tạo nhiều bao đóng trong một chức năng. Ngay khi bạn có ý tưởng về một bao đóng, có thể bạn sẽ sử dụng nó rất nhiều vì đây là một cách thuận tiện để đóng gói một chức năng với dữ liệu bổ sung. Tuy nhiên, có một số cạm bẫy. Lớn nhất được minh họa bên dưới, nhưng đây được coi là tài liệu nâng cao

Hãy để chúng tôi tạo một loạt các hàm

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
719 cho các giá trị khác nhau của tham số
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85. Mỗi hàm chỉ trả về một bộ
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
721 để chúng ta có thể dễ dàng thấy đối số và tham số là gì. Chúng tôi sử dụng
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
722 để nhanh chóng xác định từng chức năng và chúng tôi đặt các chức năng trong danh sách

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
78

Bây giờ,

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
723 là danh sách các hàm có một đối số. Gọi từng hàm và in các giá trị trả về
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 và
def h[t]:
    return t**4 + 4*t

dh = diff[h, 0.1]

from math import sin, pi
x = 2*pi
dsin = diff[sin, x, h=1E-6]
60 sẽ cho

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
79

Như chúng ta thấy, tất cả các chức năng có

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
726, i. e. , họ đã lưu trữ giá trị gần đây nhất của
def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 trước khi trả lại. Đây không phải là những gì chúng tôi muốn

Mẹo nhỏ là để

def diff[f, x, h=1E-5]:
    return [f[x+h] - f[x]]/h
85 làm đối số từ khóa trong mỗi hàm, vì giá trị của đối số từ khóa bị cố định tại thời điểm hàm được xác định

Việc sử dụng chức năng lớp là gì?

Trong toán học, đặc biệt là trong lĩnh vực lý thuyết nhóm và lý thuyết biểu diễn nhóm, hàm hạng là một hàm trên nhóm G và không đổi trên các lớp liên hợp của G. Nói cách khác, nó bất biến dưới ánh xạ liên hợp trên G. Những chức năng như vậy đóng vai trò cơ bản trong lý thuyết biểu diễn .

Khi nào sử dụng lớp trong Python?

Theo nguyên tắc chung, khi bạn có một tập hợp dữ liệu với cấu trúc cụ thể và bạn muốn thực hiện các phương pháp cụ thể trên đó , . Tuy nhiên, điều đó chỉ hợp lệ nếu bạn sử dụng nhiều cấu trúc dữ liệu trong mã của mình. Nếu toàn bộ mã của bạn sẽ không bao giờ xử lý nhiều hơn một cấu trúc.

lớp trong Python với ví dụ là gì?

Các đối tượng và lớp Python . Tương tự, một lớp là bản thiết kế cho đối tượng đó . Chúng ta có thể coi một lớp như một bản phác thảo [nguyên mẫu] của một ngôi nhà. Nó chứa tất cả các chi tiết về sàn nhà, cửa ra vào, cửa sổ, v.v.

Phương thức lớp có phải là một hàm trong Python không?

Một phương thức trong python hơi giống với một hàm, ngoại trừ nó được liên kết với các đối tượng/lớp . Các phương thức trong python rất giống với các hàm ngoại trừ hai điểm khác biệt chính. Phương thức này được sử dụng hoàn toàn cho một đối tượng mà nó được gọi. Phương thức có thể truy cập vào dữ liệu được chứa trong lớp.

Chủ Đề