Python vượt qua tham chiếu

Có hai cách biến phổ biến được sử dụng để truyền đối số trong C/C++/Perl là truyền giá trị và truyền tham chiếu. Python sử dụng một cách tương tự như vậy dựa trên kiểu dữ liệu truyền vào là đối tượng bất biến hoặc đối tượng có thể thay đổi mà sử dụng giá trị truyền hoặc tham chiếu tương ứng. Hơn nữa, trong Python công việc truyền đối số cũng trở nên linh hoạt hơn nhiều nhờ vào việc hỗ trợ 2 ký tự ‘*’ và ‘**’ khi gọi hàm. Nhờ đó, chúng ta không phải viết tường minh hay cần biết trước số lượng tham số đầu vào

Một câu hỏi nhạt toẹt của nhà phỏng vấn có thể được đưa ra [với người phỏng vấn thông thường có kiến ​​thức từ ngôn ngữ khác như Java, PHP hay C++, hoặc một chuyên gia Python thực sự và hỏi để kiểm tra xem bạn có băn khoăn không

Tuyển trăn nhiều vị trí lương cao

Python sử dụng gọi theo giá trị hay gọi theo tham chiếu?

Hai khái niệm này thực sự không tồn tại trong Python, bạn có thể đào tung cả trang tài liệu của Python cũng sẽ không thấy nói gì về khái niệm này. News is. nó không có thật. Nó không cần thiết. bạn chỉ cần hiểu chức năng hoạt động thế nào, cách Python sử dụng “name binding”. Còn không nên ngồi cãi nhau về “call-by-reference”, “call-by-value” làm gì cho mất thời gian, vô tác dụng

  • https. // tài liệu. con trăn. tổ chức/3/tìm kiếm. html?q=by+tham chiếu
  • https. // tài liệu. con trăn. tổ chức/3/tìm kiếm. html?q=by+giá trị

Call by XYZ là cái gì?

Mọi khái niệm viết sau đây không tồn tại trong Python, các thuật ngữ được viết với “từ vựng” của ngôn ngữ lập trình khác

Trong một số ngôn ngữ như C, C++, khi gọi hàm ta có truyền vào các “tham số” [truyền đối số], nếu hàm đó nhận vào một mảng [trong Python hiểu nôm na là danh sách], thì trong hàm, ta sẽ

Kiểu 1

update[danh_sach]

Kiểu 2

update[&danh_sach]

Với câu gọi hàm [hàm gọi] thứ nhất ta gọi hàm với giá trị [giá trị] của biến 

update[&danh_sach]
0. Mọi sự thay đổi trong hàm thực hiện trên đối số được gọi là thực hiện trên bản sao của 
update[&danh_sach]
0

Câu gọi hàm thứ hai ta gọi hàm với con trỏ [con trỏ] đến biến 

update[&danh_sach]
0 hay còn gọi là tham chiếu. Mọi thay đổi sẽ thay đổi trực tiếp trên 
update[&danh_sach]
0

Trình lập trình ngôn ngữ này bị ảnh hưởng bởi C thường xuyên cắt giảm khái niệm “con trỏ” để tránh gây phức tạp, vì vậy khi gọi hàm sẽ mặc định sử dụng 1 trong 2 kiểu trên. Hoặc sử dụng một chế độ hoàn toàn khác

Ví dụ

  • Gọi Java/chuyển theo giá trị
  • Gọi/chuyển PHP bằng gì đó

Call by và pass by

  • Khi nói chức năng gọi bằng , người ta đang lấy chức năng làm trọng tâm của câu chuyện
  • Khi nói lý lẽ trôi qua, người ta đang lấy lý lẽ làm trọng tâm của câu chuyện

Chỉ là hai cách tập trung khác nhau vào một công việc. gọi hàm với các đối số

Gọi hàm trong Python active thế nào?

Nếu bắt buộc phải đưa ra một từ khóa, thì đó là các đối số sẽ được “vượt qua nhiệm vụ”. Để hiểu rõ nhiệm vụ Python làm gì, bạn cần hiểu về khái niệm tên và ràng buộc trong Python

Cách hoạt động của tên và ràng buộc

x = 4
y = x
x = x + 1
print[x, y]

update[&danh_sach]
4 là mấy và 
update[&danh_sach]
5 là mấy?

Mã này đọc theo thuật ngữ của Python như sau

  • tên liên kết 
    update[&danh_sach]
    
    4 vào đối tượng 4
  • tên liên kết 
    update[&danh_sach]
    
    5 vào đối tượng mà 
    update[&danh_sach]
    
    4 HIỆN đang liên kết vào [tức 4]
  • tên liên kết 
    update[&danh_sach]
    
    4 vào đối tượng được tạo bởi x+1 [tức 5] do 
    update[&danh_sach]
    
    4 là 4, khi +1, nó sinh ra một đối tượng mới là 5

Unknown results at here.

update[&danh_sach]
4 là 5, 
update[&danh_sach]
5 là 4. Chú ý rằng 
update[&danh_sach]
5 không đi theo 
update[&danh_sach]
4, cũng không liên kết với 
update[&danh_sach]
4, nó liên kết với đối tượng mà 
update[&danh_sach]
4 liên kết tại thời điểm đó

Xem ví dụ sau tương tự, nhưng chắc chắn khác

L = [1,2,3]
K = L
L[0] = 9
print[L, K]

x = 4
y = x
x = x + 1
print[x, y]
7 là mấy?

Điều này sẽ rõ ràng, phải là câu hỏi phỏng vấn mặc định để thiết lập trình viên Python chứ không phải vài câu trộn lẫn như tiêu đề bài viết này. Vì sao?

Please read this đoạn mã theo thuật ngữ Python

  • tên liên kết _______6_______7 vào đối tượng danh sách chứa 1,2,3
  • tên liên kết 
    x = 4
    y = x
    x = x + 1
    print[x, y]
    
    8 vào đối tượng mà 
    x = 4
    y = x
    x = x + 1
    print[x, y]
    
    7 hiện tại đang liên kết [tức danh sách 1,2,3]
  • Thay đổi phần tử đầu tiên của danh sách, gán cho giá trị bằng 9

Hãy nhớ 

x = 4
y = x
x = x + 1
print[x, y]
7 và 
x = 4
y = x
x = x + 1
print[x, y]
8 chỉ là 2 tên cùng liên kết với một đối tượng, khi đối tượng này bị thay đổi, dù sử dụng qua tên 
x = 4
y = x
x = x + 1
print[x, y]
7 hay tên 
x = 4
y = x
x = x + 1
print[x, y]
8, thì thay đổi đó là thực hiện trên đối tượng đó. Kết quả tức thời sẽ cho 
x = 4
y = x
x = x + 1
print[x, y]
7 và 
x = 4
y = x
x = x + 1
print[x, y]
8 giống nhau [hay chính xác hơn, chúng là một]. Sử dụng hàm 
L = [1,2,3]
K = L
L[0] = 9
print[L, K]
8 sẽ giúp hiểu rõ hơn khi nói về đối tượng và tên

>>> L = [1,2,3]
>>> K = L
>>> L[0] = 9
>>> print[L, K]
[9, 2, 3] [9, 2, 3]
>>> id[L]
4326049992
>>> id[K]
4326049992
>>> L is K
True

L = [1,2,3]
K = L
L[0] = 9
print[L, K]
8 sẽ trả lại một số ID [ chắc chắn là duy nhất] gắn liền với đối tượng mà cái tên đó đang ràng buộc

Cơ chế hoạt động của chức năng

>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]

Cơ chế gọi chức năng của Python hoạt động như sau

  • tên ràng buộc 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    0 vào đối số thứ nhất, tức thời 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    1
  • tên ràng buộc 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    2 vào đối số thứ hai, tức thời 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    3
  • ràng buộc 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    0 vào đối tượng được tạo ra bởi tê + 1, tức 10
  • thay đổi đối tượng mà tên 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    2 đang ràng buộc tới, danh sách tức thời [1,2,3], thay đổi giá trị ứng với chỉ mục 0, tức thì sẽ có [0,2,3]
  • nên nhớ rằng 
    >>> L = [1,2,3]
    >>> K = L
    >>> L[0] = 9
    >>> print[L, K]
    [9, 2, 3] [9, 2, 3]
    >>> id[L]
    4326049992
    >>> id[K]
    4326049992
    >>> L is K
    True
    
    2 và 
    x = 4
    y = x
    x = x + 1
    print[x, y]
    
    7 cùng liên kết với 1 đối tượng. Vì vậy giờ L cũng đã bị thay đổi

Vậy làm sao để không thay đổi danh sách L và thu về một danh sách mới sau khi gọi hàm?

>>> def change[L]:
...     L = L[:] # slicing là một cách đơn giản để tạo một bản shallow copy
...     L[0] = 0
...     return L
...
>>> newL = change[L]
>>> print[L]
[1, 2, 3]
>>> print[newL]
[0, 2, 3]

note. Nếu danh sách L bao gồm các đối tượng có thể thay đổi [xem ở dưới], cần sử dụng hàm 

>>> L = [1,2,3]
>>> K = L
>>> L[0] = 9
>>> print[L, K]
[9, 2, 3] [9, 2, 3]
>>> id[L]
4326049992
>>> id[K]
4326049992
>>> L is K
True
8 trong thư viện chuẩn 
>>> L = [1,2,3]
>>> K = L
>>> L[0] = 9
>>> print[L, K]
[9, 2, 3] [9, 2, 3]
>>> id[L]
4326049992
>>> id[K]
4326049992
>>> L is K
True
9

Một số kiểu dữ liệu trong Python không cho phép thay đổi giá trị của nó sau khi tạo ra [bất biến] như int, float, str, NoneType, bool, tuple. Vì vậy, mỗi lần “thay đổi”, ta sẽ tạo ra một đối tượng mới chứa giá trị mới

>>> N = 9
>>> id[N]
4297624192
>>> N = N + 2
>>> id[N]
4297624256
>>> N
11

>>> T1 = [1,2,3]
>>> id[T1]
4326100280
>>> T1 = T1 + [3,4,5]
>>> id[T1]
4325883048
>>> print[T1]
[1, 2, 3, 3, 4, 5]

Các loại dữ liệu khác cho phép thay đổi sau khi tạo ra [có thể thay đổi]. danh sách, dict, thiết lập

>>> L = [1,2,3]
>>> id[L]
4326050504
>>> L.extend[[3,4,5]]
>>> id[L]
4326050504
>>> print[L]
[1, 2, 3, 3, 4, 5]

Với kiểu có thể thay đổi, cần đặc biệt chú ý cho phép toán bất kỳ trả về đối tượng mới, cho phép toán bất kỳ đối tượng thay đổi hiện tại

>>> L = [1,2,3]
>>> id[L]
4326050568
>>> L = L + [3,4,5]
>>> id[L]
4326095240
>>> L
[1, 2, 3, 3, 4, 5]

>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
0, 
>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
1 của danh sách đều thay đổi phương thức gọi đối tượng. Magic 
>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
2 list with list, sinh ra một danh sách mới

Python sử dụng chuyển theo phép gán, gọi theo tham chiếu đối tượng

Vượt qua nhiệm vụ là khái niệm lấy từ , khi đó người ta bắt buộc phải giải thích khái niệm này cho những người đã biết ngôn ngữ lập trình khác. Tên trong hàm sẽ liên kết với các đối tượng mà đối số đang liên kết tới

Trong hướng dẫn Python, có viết  – yup, tôi đã nói dối 😒

:

Tên đề cập đến các đối tượng

Liệu bạn có thể sử dụng một thuật ngữ khác là “gọi tên” ??

Chốt, thông tin

Để khỏi đau đầu về những điều này, chỉ cần nắm chắc các khái niệm 

>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
3, 
>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
4, 
>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
5, 
>>> def change[numb, ns]:
...     numb = numb + 1
...     ns[0] = 0
...     return None
...
>>> N = 9
>>> L = [1,2,3]
>>> change[N, L]
>>> print[N, L]
9 [0, 2, 3]
6 là đủ biết chương trình chạy thế nào. You don't know Python name is call-by-gì?

Trên internet có nhiều nơi hỏi đáp, cố đưa ra một cái tên, nhưng những cái tên đó không có trong tài liệu chính của Python

Chủ Đề