Truyền theo giá trị và truyền theo tham chiếu trong Python là gì?

Điều quan trọng là phải hiểu cơ chế truyền tham số trong Python, cơ chế này thường cho phép chúng ta mắc ít lỗi hơn và nâng cao hiệu quả khi viết mã

Truyền theo giá trị so với Truyền theo tham chiếu

Nếu bạn có nền tảng ngôn ngữ lập trình khác, chẳng hạn như C/C++, thì dễ hiểu rằng có hai kiểu truyền tham số phổ biến. pass-by-value và pass-by-reference

  • giá trị vượt qua. Sao chép giá trị của tham số và chuyển nó vào biến mới trong hàm
  • chuyển qua tham chiếu. Truyền tham chiếu của tham số cho biến mới, để biến ban đầu và biến mới sẽ trỏ đến cùng một địa chỉ bộ nhớ

Vậy làm cách nào để truyền tham số hoạt động trong Python?

Trước khi trả lời câu hỏi này, trước tiên chúng ta hãy hiểu các nguyên tắc cơ bản của các biến và phép gán trong Python

Các biến và bài tập trong Python

Hãy bắt đầu bằng cách xem ví dụ mã Python sau

a = 1
b = a
a = a + 1

Ở đây, 1 đầu tiên được gán cho a, tức là, a trỏ tới đối tượng 1, như thể hiện trong sơ đồ sau

Khi đó,

l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
0 có nghĩa là, hãy để biến
l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
1 đồng thời trỏ đến đối tượng 1. Lưu ý ở đây rằng các đối tượng trong Python có thể được trỏ tới hoặc tham chiếu bởi nhiều biến. Bây giờ lưu đồ trông như thế này

Cuối cùng là câu lệnh

l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
3. Cần lưu ý rằng các kiểu dữ liệu Python, chẳng hạn như số nguyên [int], chuỗi [string], v.v. , là bất biến. Vì vậy,
l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
3, không tăng giá trị của a lên 1, nhưng có nghĩa là một đối tượng mới có giá trị là
l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
6 được tạo và a trỏ tới nó. Nhưng
l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
1 vẫn không thay đổi và vẫn trỏ đến đối tượng 1

Tại thời điểm này, bạn có thể thấy rằng một phép gán đơn giản

l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
0 không có nghĩa là một đối tượng mới được tạo lại, mà là cùng một đối tượng được trỏ hoặc tham chiếu bởi nhiều biến

Đồng thời, trỏ đến cùng một đối tượng không có nghĩa là hai biến bị ràng buộc với nhau. Nếu bạn gán lại một trong các biến, nó sẽ không ảnh hưởng đến giá trị của các biến khác

Bây giờ chúng ta hãy xem một ví dụ về danh sách

l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]

Lúc đầu, chúng tôi để danh sách

l = [1, 2, 3]
del l
1 và
l = [1, 2, 3]
del l
2 trỏ đến đối tượng [1, 2, 3] cùng một lúc

Vì danh sách có thể thay đổi, nên

l = [1, 2, 3]
del l
3 không tạo danh sách mới, nó chỉ chèn phần tử 4 vào cuối danh sách ban đầu, danh sách này trở thành [1, 2, 3, 4]. Do
l = [1, 2, 3]
del l
1 và
l = [1, 2, 3]
del l
2 trỏ đến danh sách này cùng một lúc nên sự thay đổi của danh sách sẽ được phản ánh đồng thời ở hai biến là
l = [1, 2, 3]
del l
1 và
l = [1, 2, 3]
del l
2, khi đó giá trị của
l = [1, 2, 3]
del l
1 và
l = [1, 2, 3]
del l
2 sẽ trở thành [1, 2,

Ngoài ra, lưu ý rằng các biến trong Python có thể bị xóa, nhưng các đối tượng không thể bị xóa. Ví dụ đoạn mã sau

l = [1, 2, 3]
del l

def my_func1[b]:
b = 2
a = 1
my_func1[a]
a
1
0 xóa biến
def my_func1[b]:
b = 2
a = 1
my_func1[a]
a
1
1, và bạn không thể truy cập vào
def my_func1[b]:
b = 2
a = 1
my_func1[a]
a
1
1 từ bây giờ, nhưng đối tượng [1, 2, 3] vẫn tồn tại. Khi một chương trình Python chạy, hệ thống thu gom rác của chính nó sẽ theo dõi mọi tham chiếu đối tượng. Nếu [1, 2, 3] được tham chiếu ở những nơi khác ngoài
def my_func1[b]:
b = 2
a = 1
my_func1[a]
a
1
1, nó sẽ không được thu thập, nếu không, nó sẽ được thu thập

Vì vậy, trong Python

  • Việc gán một biến chỉ có nghĩa là biến đó trỏ đến một đối tượng và không có nghĩa là đối tượng được sao chép vào biến;
  • Thay đổi các đối tượng có thể thay đổi [danh sách, từ điển, bộ, v.v. ] ảnh hưởng đến tất cả các biến trỏ đến đối tượng đó
  • Đối với các đối tượng không thay đổi [chuỗi, int, bộ dữ liệu, v.v. ], giá trị của tất cả các biến trỏ đến đối tượng luôn giống nhau và không thay đổi. Nhưng khi giá trị của một đối tượng bất biến được cập nhật bởi một số thao tác [+= v.v. ], một đối tượng mới được trả về
  • Các biến có thể bị xóa, nhưng các đối tượng không thể bị xóa
Truyền đối số cho các hàm Python

Hãy xem trích dẫn chính thức của Python

“Hãy nhớ rằng các đối số được truyền bằng phép gán trong Python. Vì phép gán chỉ tạo tham chiếu đến các đối tượng, nên không có bí danh giữa tên đối số trong trình gọi và callee, do đó không có tham chiếu gọi theo tham chiếu mỗi Se. ”

Truyền đối số của Python được truyền theo phép gán hoặc truyền theo tham chiếu đối tượng. Các kiểu dữ liệu trong Python đều là đối tượng nên khi truyền tham số chỉ để biến mới và biến ban đầu trỏ về cùng một đối tượng, không có chuyện truyền giá trị hay truyền tham chiếu

Ví dụ

def my_func1[b]:
b = 2
a = 1
my_func1[a]
a
1

Tham số truyền vào đây làm cho các biến a

l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
1 trỏ đến đối tượng 1 cùng một lúc. Nhưng khi chúng ta đến
def my_func1[b]:
b = 2
a = 1
my_func1[a]
a
1
7, hệ thống sẽ tạo một đối tượng mới với giá trị là
l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
6 và để
l1 = [1, 2, 3]
l2 = l1
l1.append[4]
l1
[1, 2, 3, 4]
l2
[1, 2, 3, 4]
1 trỏ tới nó; . Vì vậy, giá trị của a không thay đổi, nó vẫn là 1

Tuy nhiên, khi một đối tượng có thể thay đổi được truyền dưới dạng tham số cho hàm, việc thay đổi giá trị của đối tượng có thể thay đổi sẽ ảnh hưởng đến tất cả các biến trỏ đến nó. Ví dụ

def my_func3[l2]:
l2.append[4]
l1 = [1, 2, 3]
my_func3[l1]
l1
[1, 2, 3, 4]

Ở đây

l = [1, 2, 3]
del l
1 và
l = [1, 2, 3]
del l
2 đầu tiên cả hai đều trỏ đến danh sách có giá trị [1, 2, 3]. Tuy nhiên, do danh sách có nhiều biến khi hàm
def my_func3[l2]:
l2.append[4]
l1 = [1, 2, 3]
my_func3[l1]
l1
[1, 2, 3, 4]
5 được thực thi và một phần tử mới
def my_func3[l2]:
l2.append[4]
l1 = [1, 2, 3]
my_func3[l1]
l1
[1, 2, 3, 4]
6 được thêm vào cuối danh sách nên giá trị của các biến
l = [1, 2, 3]
del l
1 và
l = [1, 2, 3]
del l
2 cũng bị thay đổi

Tuy nhiên, ví dụ sau đây, dường như thêm một phần tử mới vào danh sách, lại mang lại kết quả khác biệt đáng kể

def my_func4[l2]:
l2 = l2 + [4]
l1 = [1, 2, 3]
my_func4[l1]
l1
[1, 2, 3]

Điều này là do câu lệnh

def my_func3[l2]:
l2.append[4]
l1 = [1, 2, 3]
my_func3[l1]
l1
[1, 2, 3, 4]
9, có nghĩa là một danh sách mới với "phần tử 4 được thêm vào cuối" được tạo và
l = [1, 2, 3]
del l
2 trỏ tới đối tượng mới này

Phần kết luận

Không giống như các ngôn ngữ khác, việc truyền tham số trong Python không phải theo giá trị hay theo tham chiếu, mà theo phép gán hoặc tham chiếu đến các đối tượng

Cần lưu ý rằng phép gán hoặc chuyển tham chiếu của đối tượng ở đây không trỏ đến một địa chỉ bộ nhớ cụ thể mà là một đối tượng cụ thể

  • Nếu một đối tượng có thể thay đổi, khi nó thay đổi, tất cả các biến trỏ đến đối tượng này sẽ thay đổi theo
  • Nếu đối tượng là bất biến, một phép gán đơn giản chỉ có thể thay đổi giá trị của một trong các biến, khiến các biến còn lại không bị ảnh hưởng

Rõ ràng muốn thay đổi giá trị của biến thông qua hàm thường có 2 cách

  • Một là chuyển trực tiếp vào một kiểu dữ liệu biến [chẳng hạn như danh sách, từ điển, tập hợp] làm tham số và sửa đổi nó trực tiếp;
  • Hai là tạo một biến mới để lưu giá trị đã sửa, sau đó trả về biến ban đầu

Trong công việc thực tế, chúng tôi thích sử dụng cái sau hơn, vì cách diễn đạt của nó rõ ràng và ít sai sót hơn

Truyền theo giá trị và truyền theo tham chiếu là gì?

Đầu tiên, chuyển theo giá trị và chuyển theo tham chiếu nghĩa là gì? . Các giá trị tham số của phương thức được sao chép sang một biến khác và sau đó đối tượng được sao chép được chuyển sang phương thức. Phương pháp sử dụng bản sao. Chuyển qua tham chiếu. Bí danh hoặc tham chiếu đến tham số thực tế được truyền cho phương thức

Python truyền theo giá trị hay truyền theo tham chiếu?

Python truyền các đối số không phải theo tham chiếu hay theo giá trị mà theo phép gán.

Điều gì được truyền theo phương thức giá trị trong Python?

Có phải giá trị truyền qua của Python không? . Điều này có nghĩa là bạn có thể sửa đổi các đối số theo cách bạn muốn và bạn sẽ không thể thay đổi trạng thái của chương trình bên ngoài chức năng. when you call a function with a set of arguments, the data is copied into the function. This means that you can modify the arguments however you please and that you won't be able to alter the state of the program outside the function.

Có chuyển qua tham chiếu trong Python không?

Python luôn sử dụng các giá trị chuyển qua tham chiếu . Không có bất kỳ ngoại lệ. Bất kỳ phép gán biến nào có nghĩa là sao chép giá trị tham chiếu.

Chủ Đề