Hướng dẫn python out parameter - python out tham số

I have one User defined Object. I want to pass as reference (out parameter) so that value of input Object will be changed inside function and return to called function. This can be achieved by using list or Dictionary i.e mutable object. But How to achieve with User defined object without using list & Dictionary. Check below code snippet as example:-

Show
class Test:          
    def __init__(self,data):
        self.data = data

def display(root):    # Simple Display function
    print(root.data)

#Don't want to use List to do pass by reference and out parameter. Instead pass object itself.
def assign(root,args): 
    if root is not None:
        args[0] = root

#Passed object itself, not as List     
def assign1(root,temp):
    if root is not None:
        temp = root

#Driver Function call    
root = Test(10)
display(root)
temp = None
args = [temp]
assign(root,args)   # Function in which args passed as out parameter
display(args[0])    # Gives Output: 10 

temp1 = None 
assign1(root,temp1) # Function in which object passed as out parameter
print(temp1)        # Gives Output: None
display(temp1)      # AttributeError: 'NoneType' object has no attribute 'data'

May be i am missing something.

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem cùng với hướng dẫn bằng văn bản để hiểu sâu hơn về sự hiểu biết của bạn: vượt qua tham chiếu trong Python: Thực tiễn tốt nhất This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Pass by Reference in Python: Best Practices This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Pass by Reference in Python: Best Practices

Nội dung chính ShowShow

  • Xác định vượt qua theo tham chiếu
  • Tương phản vượt qua bằng cách tham chiếu và vượt qua giá trị
  • Sử dụng các cấu trúc tham chiếu vượt qua
  • Tránh các đối tượng trùng lặp
  • Trả về nhiều giá trị
  • May mắn thay, Python đã hỗ trợ trả về nhiều giá trị. Nói đúng ra, một hàm Python trả về nhiều giá trị thực sự trả về một tuple chứa mỗi giá trị:
  • Vượt qua các cuộc tranh luận trong Python
  • Hiểu nhiệm vụ trong Python
  • Khám phá các đối số chức năng
  • Bằng cách kiểm tra các không gian tên và số lượng tham chiếu bên trong các hàm, bạn có thể thấy rằng các đối số chức năng hoạt động chính xác giống như các bài tập: Python tạo các ràng buộc trong hàm tên tên cục bộ giữa các định danh và đối tượng Python đại diện cho các giá trị đối số. Mỗi ràng buộc này sẽ tăng bộ đếm tham chiếu đối tượng.
  • Tốt hơn nhiều! Bạn tránh tất cả các vấn đề tiềm năng với các biến toàn cầu và bằng cách yêu cầu một đối số, bạn làm cho chức năng của bạn rõ ràng hơn.
  • Nếu bạn cần vận hành trên nhiều giá trị, thì bạn có thể viết các hàm đơn mục đích trả về nhiều giá trị, sau đó (Re) gán các giá trị đó cho các biến. Đây là một ví dụ:
  • Thực hành tốt nhất: Sử dụng từ điển và danh sách
  • Mặc dù danh sách các loại ánh xạ aren, bạn có thể sử dụng chúng theo cách tương tự như từ điển vì hai đặc điểm quan trọng: khả năng đăng ký và khả năng đột biến. Những đặc điểm này đáng để giải thích thêm một chút, nhưng trước tiên, hãy để xem các thực tiễn tốt nhất để bắt chước vượt qua bằng cách tham khảo bằng danh sách Python.
  • Làm thế nào để vượt qua các tham số hoạt động?
  • Tham số đi qua trong Python với ví dụ là gì?
  • Tham số có cần thiết trong Python không?

Các giá trị cho các tham số không tùy chọn nên được truyền nếu không nó sẽ gây ra lỗi.Giá trị của các đối số mặc định có thể được truyền hoặc bỏ qua.. The value of the default arguments can be either passed or ignored.references to existing variables, which is known as pass by reference. Other languages handle them as independent values, an approach known as pass by value.

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem cùng với hướng dẫn bằng văn bản để hiểu sâu hơn về sự hiểu biết của bạn: vượt qua tham chiếu trong Python: Thực tiễn tốt nhất This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Pass by Reference in Python: Best Practices

Nội dung chính Show

  • Xác định vượt qua theo tham chiếupass by reference and why you’d want to do so
  • Tương phản vượt qua bằng cách tham chiếu và vượt qua giá trịpassing by value and Python’s unique approach
  • Sử dụng các cấu trúc tham chiếu vượt quafunction arguments behave in Python
  • Tránh các đối tượng trùng lặpmutable types to pass by reference in Python
  • Trả về nhiều giá trịbest practices are for replicating pass by reference in Python

Xác định vượt qua theo tham chiếu

Tương phản vượt qua bằng cách tham chiếu và vượt qua giá trị

  • Pass có nghĩa là cung cấp một đối số cho một chức năng. means to provide an argument to a function. means to provide an argument to a function.
  • Bằng cách tham khảo có nghĩa là đối số mà bạn chuyển đến hàm là một tham chiếu đến một biến đã tồn tại trong bộ nhớ thay vì một bản sao độc lập của biến đó. means that the argument you’re passing to the function is a reference to a variable that already exists in memory rather than an independent copy of that variable. means that the argument you’re passing to the function is a reference to a variable that already exists in memory rather than an independent copy of that variable.

Vì bạn đã cung cấp cho chức năng một tham chiếu đến một biến hiện có, tất cả các hoạt động được thực hiện trên tài liệu tham khảo này sẽ ảnh hưởng trực tiếp đến biến mà nó đề cập đến. Hãy cùng xem xét một số ví dụ về cách thức hoạt động trong thực tế.

Dưới đây, bạn sẽ thấy cách truyền các biến bằng cách tham chiếu trong C#. Lưu ý việc sử dụng từ khóa

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
2 trong các dòng được tô sáng:
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}

Như bạn có thể thấy,

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
3 của
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
4 phải được khai báo với từ khóa
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
2 và bạn cũng phải sử dụng từ khóa khi gọi hàm. Sau đó, đối số sẽ được chuyển qua bằng cách tham chiếu và có thể được sửa đổi tại chỗ.

Python không có từ khóa

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
2 hoặc bất cứ điều gì tương đương với nó. Nếu bạn cố gắng sao chép ví dụ trên càng gần càng tốt trong Python, thì bạn sẽ thấy các kết quả khác nhau:

>>>

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4

Trong trường hợp này, biến

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
7 không bị thay đổi tại chỗ. Có vẻ như Python coi đối số được cung cấp của bạn là một giá trị độc lập hơn là một tham chiếu đến một biến hiện có. Điều này có nghĩa là Python chuyển các đối số theo giá trị chứ không phải bằng tham chiếu?

Không hẳn. Python chuyển các đối số không bằng cách tham chiếu cũng như giá trị, mà bằng cách gán. Dưới đây, bạn sẽ nhanh chóng khám phá các chi tiết về việc chuyển bằng giá trị và vượt qua bằng cách tham khảo trước khi xem xét kỹ hơn theo cách tiếp cận của Python. Sau đó, bạn sẽ đi qua một số thực tiễn tốt nhất để đạt được sự tương đương của việc vượt qua bằng cách tham khảo trong Python.by assignment. Below, you’ll quickly explore the details of passing by value and passing by reference before looking more closely at Python’s approach. After that, you’ll walk through some best practices for achieving the equivalent of passing by reference in Python.by assignment. Below, you’ll quickly explore the details of passing by value and passing by reference before looking more closely at Python’s approach. After that, you’ll walk through some best practices for achieving the equivalent of passing by reference in Python.

Tương phản vượt qua bằng cách tham chiếu và vượt qua giá trị

Khi bạn vượt qua các đối số chức năng bằng tham chiếu, các đối số đó chỉ tham khảo các giá trị hiện có. Ngược lại, khi bạn vượt qua các đối số theo giá trị, những đối số đó trở thành bản sao độc lập của các giá trị ban đầu.

Hãy để xem lại ví dụ C#, lần này mà không cần sử dụng từ khóa

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
2. Điều này sẽ khiến chương trình sử dụng hành vi mặc định chuyển bằng giá trị:
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
0

Ở đây, bạn có thể thấy rằng

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
9 không sửa đổi biến ban đầu. Thay vào đó,
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
20 là một bản sao độc lập của biến ban đầu
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
7. Mặc dù điều đó phù hợp với hành vi mà bạn sẽ thấy trong Python, hãy nhớ rằng Python không chính xác vượt qua giá trị. Hãy để chứng minh điều đó.

Python sườn tích hợp

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
22 trả về một số nguyên đại diện cho địa chỉ bộ nhớ của đối tượng mong muốn. Sử dụng
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
22, bạn có thể xác minh các xác nhận sau:
  1. Các đối số chức năng ban đầu đề cập đến cùng một địa chỉ với các biến ban đầu của chúng.
  2. Việc chỉ định lại đối số trong hàm cung cấp cho nó một địa chỉ mới trong khi biến ban đầu vẫn chưa được sửa đổi.

Trong ví dụ dưới đây, lưu ý rằng địa chỉ của

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
24 ban đầu khớp với
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
25 nhưng thay đổi sau khi phân công lại, trong khi địa chỉ của
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
25 không bao giờ thay đổi:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840

Trong trường hợp này, biến

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
7 không bị thay đổi tại chỗ. Có vẻ như Python coi đối số được cung cấp của bạn là một giá trị độc lập hơn là một tham chiếu đến một biến hiện có. Điều này có nghĩa là Python chuyển các đối số theo giá trị chứ không phải bằng tham chiếu?

Không hẳn. Python chuyển các đối số không bằng cách tham chiếu cũng như giá trị, mà bằng cách gán. Dưới đây, bạn sẽ nhanh chóng khám phá các chi tiết về việc chuyển bằng giá trị và vượt qua bằng cách tham khảo trước khi xem xét kỹ hơn theo cách tiếp cận của Python. Sau đó, bạn sẽ đi qua một số thực tiễn tốt nhất để đạt được sự tương đương của việc vượt qua bằng cách tham khảo trong Python.by assignment. Below, you’ll quickly explore the details of passing by value and passing by reference before looking more closely at Python’s approach. After that, you’ll walk through some best practices for achieving the equivalent of passing by reference in Python.

Tương phản vượt qua bằng cách tham chiếu và vượt qua giá trị

Khi bạn vượt qua các đối số chức năng bằng tham chiếu, các đối số đó chỉ tham khảo các giá trị hiện có. Ngược lại, khi bạn vượt qua các đối số theo giá trị, những đối số đó trở thành bản sao độc lập của các giá trị ban đầu.

Hãy để xem lại ví dụ C#, lần này mà không cần sử dụng từ khóa

>>> def main(): ... n = 9001 ... print(f"Initial address of n: {id(n)}") ... increment(n) ... print(f" Final address of n: {id(n)}") ... >>> def increment(x): ... print(f"Initial address of x: {id(x)}") ... x += 1 ... print(f" Final address of x: {id(x)}") ... >>> main() Initial address of n: 140562586057840 Initial address of x: 140562586057840 Final address of x: 140562586057968 Final address of n: 140562586057840 2. Điều này sẽ khiến chương trình sử dụng hành vi mặc định chuyển bằng giá trị:>>> def main(): ... n = 9001 ... print(f"Initial address of n: {id(n)}") ... increment(n) ... print(f" Final address of n: {id(n)}") ... >>> def increment(x): ... print(f"Initial address of x: {id(x)}") ... x += 1 ... print(f" Final address of x: {id(x)}") ... >>> main() Initial address of n: 140562586057840 Initial address of x: 140562586057840 Final address of x: 140562586057968 Final address of n: 140562586057840 0

Ở đây, bạn có thể thấy rằng

Tuy nhiên, trong Python, đây không bao giờ là vấn đề. Bạn sẽ thấy tại sao trong phần tiếp theo.

Trả về nhiều giá trị

Một trong những ứng dụng phổ biến nhất của việc truyền bằng tham chiếu là tạo một hàm làm thay đổi giá trị của các tham số tham chiếu trong khi trả về một giá trị riêng biệt. Bạn có thể sửa đổi ví dụ C# Pass-By-Reference của mình để minh họa kỹ thuật này:

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
2

Trong ví dụ trên,

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
23 trả về một chuỗi lời chào và cũng sửa đổi giá trị của
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24. Bây giờ hãy cố gắng tái tạo điều này càng gần càng tốt trong Python:

>>>

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
2
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Về bản chất, các tham số tham chiếu trong C# cho phép hàm không chỉ trả về một giá trị mà còn hoạt động trên các tham số bổ sung. Điều này tương đương với việc trả về nhiều giá trị!

May mắn thay, Python đã hỗ trợ trả về nhiều giá trị. Nói đúng ra, một hàm Python trả về nhiều giá trị thực sự trả về một tuple chứa mỗi giá trị:

>>>

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
2
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Về bản chất, các tham số tham chiếu trong C# cho phép hàm không chỉ trả về một giá trị mà còn hoạt động trên các tham số bổ sung. Điều này tương đương với việc trả về nhiều giá trị!

>>>

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
2
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Về bản chất, các tham số tham chiếu trong C# cho phép hàm không chỉ trả về một giá trị mà còn hoạt động trên các tham số bổ sung. Điều này tương đương với việc trả về nhiều giá trị!reassign your

May mắn thay, Python đã hỗ trợ trả về nhiều giá trị. Nói đúng ra, một hàm Python trả về nhiều giá trị thực sự trả về một tuple chứa mỗi giá trị:

>>>

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
2
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Về bản chất, các tham số tham chiếu trong C# cho phép hàm không chỉ trả về một giá trị mà còn hoạt động trên các tham số bổ sung. Điều này tương đương với việc trả về nhiều giá trị!

May mắn thay, Python đã hỗ trợ trả về nhiều giá trị. Nói đúng ra, một hàm Python trả về nhiều giá trị thực sự trả về một tuple chứa mỗi giá trị:

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
6
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
8
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Về bản chất, các tham số tham chiếu trong C# cho phép hàm không chỉ trả về một giá trị mà còn hoạt động trên các tham số bổ sung. Điều này tương đương với việc trả về nhiều giá trị!reassign your

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 variable with each call to
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
23:

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
2
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Như bạn có thể thấy, để trả về nhiều giá trị, bạn chỉ có thể sử dụng từ khóa
  1. using System;
    
    // Source:
    // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
    class Program
    {
        static void Main(string[] args)
        {
            int arg;
    
            // Passing by reference.
            // The value of arg in Main is changed.
            arg = 4;
            squareRef(ref arg);
            Console.WriteLine(arg);
            // Output: 16
        }
    
        static void squareRef(ref int refParameter)
        {
            refParameter *= refParameter;
        }
    }
    
    26 theo sau là các giá trị hoặc biến được phân tách bằng dấu phẩy.
    , then the output parameter will be set to the resulting integer, and the function will return
    using System;
    
    // Source:
    // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
    class Program
    {
        static void Main(string[] args)
        {
            int arg;
    
            // Passing by reference.
            // The value of arg in Main is changed.
            arg = 4;
            squareRef(ref arg);
            Console.WriteLine(arg);
            // Output: 16
        }
    
        static void squareRef(ref int refParameter)
        {
            refParameter *= refParameter;
        }
    }
    
    68.
  2. Được trang bị kỹ thuật này, bạn có thể thay đổi câu lệnh , then the output parameter will be set to
    using System;
    
    // Source:
    // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
    class Program
    {
        static void Main(string[] args)
        {
            int arg;
    
            // Passing by reference.
            // The value of arg in Main is changed.
            arg = 4;
            squareRef(ref arg);
            Console.WriteLine(arg);
            // Output: 16
        }
    
        static void squareRef(ref int refParameter)
        {
            refParameter *= refParameter;
        }
    }
    
    62, and the function will return
    using System;
    
    // Source:
    // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
    class Program
    {
        static void Main(string[] args)
        {
            int arg;
    
            // Passing by reference.
            // The value of arg in Main is changed.
            arg = 4;
            squareRef(ref arg);
            Console.WriteLine(arg);
            // Output: 16
        }
    
        static void squareRef(ref int refParameter)
        {
            refParameter *= refParameter;
        }
    }
    
    80.

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
26 trong
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
23 từ mã Python trước đó của bạn để trả về cả lời chào và một bộ đếm:
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
7

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
0

Điều đó vẫn không có vẻ đúng. Mặc dù

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
1

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
23 hiện trả về nhiều giá trị, nhưng chúng được in dưới dạng
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
60, đó là ý định của bạn. Hơn nữa, biến
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 ban đầu vẫn ở
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
62.

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
2

Để làm sạch đầu ra của bạn và nhận kết quả mong muốn, bạn sẽ phải gán lại biến

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 của mình với mỗi cuộc gọi đến
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
23:, then the output parameter will be set to the resulting integer, and the function will return
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
68.

Bây giờ, sau khi chỉ định lại từng biến với một cuộc gọi đến

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
23, bạn có thể thấy kết quả mong muốn!, then the output parameter will be set to
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
62, and the function will return
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
80.

Gán các giá trị trả về cho các biến là cách tốt nhất để đạt được kết quả tương tự như truyền bằng cách tham chiếu trong Python. Bạn sẽ tìm hiểu lý do tại sao, cùng với một số phương pháp bổ sung, trong phần về các thực tiễn tốt nhất.

>>>

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
3

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
2
using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
24 được tăng lên trong ví dụ trên bởi vì, như bạn đã học trước đây, Python không có cách nào để truyền giá trị bằng cách tham khảo. Vậy làm thế nào bạn có thể đạt được kết quả tương tự như bạn đã làm với C#?

Về bản chất, các tham số tham chiếu trong C# cho phép hàm không chỉ trả về một giá trị mà còn hoạt động trên các tham số bổ sung. Điều này tương đương với việc trả về nhiều giá trị!

May mắn thay, Python đã hỗ trợ trả về nhiều giá trị. Nói đúng ra, một hàm Python trả về nhiều giá trị thực sự trả về một tuple chứa mỗi giá trị:

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
4

Với khả năng các chức năng Python trả về các loại dữ liệu khác nhau, giờ đây bạn có thể sử dụng chức năng này trong một câu lệnh có điều kiện. Nhưng bằng cách nào? Bạn sẽ phải gọi hàm trước, gán giá trị trả về của nó và sau đó kiểm tra giá trị?

Bằng cách tận dụng tính linh hoạt của Python, trong các loại đối tượng, cũng như các biểu thức gán mới trong Python 3.8, bạn có thể gọi hàm đơn giản này trong câu lệnh

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
84 có điều kiện và nhận giá trị trả về nếu kiểm tra vượt qua:

>>>

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
5

Ồ! Phiên bản Python này của

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
82 thậm chí còn mạnh hơn phiên bản C#, cho phép bạn sử dụng nó trong các câu lệnh có điều kiện và trong các biểu thức số học.

Với một chút khéo léo, bạn đã sao chép một mô hình chuyển qua cụ thể và hữu ích mà không thực sự truyền cho các đối số bằng cách tham khảo. Trên thực tế, bạn lại một lần nữa gán các giá trị trả về khi sử dụng toán tử biểu thức gán (____ 78) và sử dụng giá trị trả về trực tiếp trong các biểu thức python.assigning return values when using the assignment expression operator(assigning return values when using the assignment expression operator(

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
88) and using the return value directly in Python expressions.

Cho đến nay, bạn đã học được những gì vượt qua bằng cách tham khảo có nghĩa là, nó khác với việc vượt qua giá trị như thế nào và cách tiếp cận của Python khác với cả hai. Bây giờ bạn đã sẵn sàng để xem xét kỹ hơn về cách Python xử lý các đối số chức năng!

Vượt qua các cuộc tranh luận trong Python

Python chuyển các đối số bằng cách chuyển nhượng. Đó là, khi bạn gọi hàm python, mỗi đối số hàm trở thành một biến mà giá trị truyền được gán.

Do đó, bạn có thể tìm hiểu các chi tiết quan trọng về cách Python xử lý các đối số chức năng bằng cách hiểu cách thức cơ chế gán hoạt động, ngay cả các chức năng bên ngoài.

Hiểu nhiệm vụ trong Python

Tham khảo ngôn ngữ Python cho các câu lệnh gán cung cấp các chi tiết sau:

  • Nếu mục tiêu gán là một định danh hoặc tên biến, thì tên này bị ràng buộc với đối tượng. Ví dụ, trong
    using System;
    
    // Source:
    // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
    class Program
    {
        static void Main(string[] args)
        {
            int arg;
    
            // Passing by reference.
            // The value of arg in Main is changed.
            arg = 4;
            squareRef(ref arg);
            Console.WriteLine(arg);
            // Output: 16
        }
    
        static void squareRef(ref int refParameter)
        {
            refParameter *= refParameter;
        }
    }
    
    89,
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    24 là tên và
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    21 là đối tượng.
  • Nếu tên đã bị ràng buộc với một đối tượng riêng biệt, thì nó sẽ liên kết lại với đối tượng mới. Ví dụ: nếu
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    24 đã
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    21 và bạn phát hành
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    24, thì tên biến
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    24 được giới hạn lại thành
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    26.

Tất cả các đối tượng Python được thực hiện trong một cấu trúc cụ thể. Một trong những thuộc tính của cấu trúc này là một bộ đếm theo dõi số lượng tên đã bị ràng buộc với đối tượng này.

Hãy để ví dụ về ví dụ

using System;

// Source:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}
89 và kiểm tra điều gì xảy ra khi bạn gán giá trị cho một biến mới:
  1. Nếu một đối tượng đại diện cho giá trị
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    2 1 đã tồn tại, thì nó đã được truy xuất. Nếu không, nó đã tạo ra.
  2. Bộ đếm tham chiếu của đối tượng này được tăng lên.
  3. Một mục được thêm vào không gian tên hiện tại để liên kết định danh
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    24 với đối tượng đại diện cho
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    21. Mục nhập này trên thực tế là một cặp giá trị khóa được lưu trữ trong một từ điển! Một đại diện của từ điển đó được trả lại bởi
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    71 hoặc
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    72.

Bây giờ ở đây, những gì xảy ra nếu bạn phân công lại

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
24 thành một giá trị khác:
  1. Bộ đếm tham chiếu của đối tượng đại diện cho
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    21 bị giảm.
  2. Bộ đếm tham chiếu của đối tượng đại diện cho giá trị mới được tăng lên.
  3. Từ điển cho không gian tên hiện tại được cập nhật để liên hệ
    >>> def main():
    ...     n = 9001
    ...     print(f"Initial address of n: {id(n)}")
    ...     increment(n)
    ...     print(f"  Final address of n: {id(n)}")
    ...
    >>> def increment(x):
    ...     print(f"Initial address of x: {id(x)}")
    ...     x += 1
    ...     print(f"  Final address of x: {id(x)}")
    ...
    >>> main()
    Initial address of n: 140562586057840
    Initial address of x: 140562586057840
      Final address of x: 140562586057968
      Final address of n: 140562586057840
    
    24 với đối tượng đại diện cho giá trị mới.

Python cho phép bạn có được số lượng tham chiếu cho các giá trị tùy ý với hàm

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
76. Bạn có thể sử dụng nó để minh họa cách gán tăng và giảm các bộ đếm tham chiếu này. Lưu ý rằng trình thông dịch tương tác sử dụng hành vi sẽ mang lại kết quả khác nhau, vì vậy bạn nên chạy mã sau từ một tệp:
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
6

Tập lệnh này sẽ hiển thị số lượng tham chiếu cho từng giá trị trước khi gán, sau khi gán và sau khi phân công lại:

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
7

Những kết quả này minh họa mối quan hệ giữa các định danh (tên biến) và các đối tượng Python đại diện cho các giá trị riêng biệt. Khi bạn gán nhiều biến cho cùng một giá trị, Python sẽ tăng bộ đếm tham chiếu cho đối tượng hiện có và cập nhật không gian tên hiện tại thay vì tạo các đối tượng trùng lặp trong bộ nhớ.

Trong phần tiếp theo, bạn sẽ xây dựng dựa trên sự hiểu biết hiện tại của mình về các hoạt động chuyển nhượng bằng cách khám phá cách Python xử lý các đối số chức năng.

Khám phá các đối số chức năng

Đối số chức năng trong Python là các biến cục bộ. Điều đó nghĩa là gì? Địa phương là một trong những phạm vi Python. Các phạm vi này được thể hiện bằng từ điển không gian tên được đề cập trong phần trước. Bạn có thể sử dụng

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
71 và
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
72 để truy xuất từ ​​điển không gian tên địa phương và toàn cầu, tương ứng.local variables. What does that mean? Local is one of Python’s scopes. These scopes are represented by the namespace dictionaries mentioned in the previous section. You can use
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
71 and
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
72 to retrieve the local and global namespace dictionaries, respectively.local variables. What does that mean? Local is one of Python’s scopes. These scopes are represented by the namespace dictionaries mentioned in the previous section. You can use
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
71 and
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
72 to retrieve the local and global namespace dictionaries, respectively.

Sau khi thực hiện, mỗi hàm có không gian tên cục bộ riêng:

>>>

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
8

Sử dụng

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
71, bạn có thể chứng minh rằng các đối số chức năng trở thành các biến thường xuyên trong không gian tên cục bộ của hàm. Hãy để thêm một đối số,
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
00, vào chức năng:

>>>

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
9

Sử dụng

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
71, bạn có thể chứng minh rằng các đối số chức năng trở thành các biến thường xuyên trong không gian tên cục bộ của hàm. Hãy để thêm một đối số,
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
00, vào chức năng:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
00

Sử dụng

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
71, bạn có thể chứng minh rằng các đối số chức năng trở thành các biến thường xuyên trong không gian tên cục bộ của hàm. Hãy để thêm một đối số,
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
00, vào chức năng:

Bạn cũng có thể sử dụng

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
76 để hiển thị cách các đối số chức năng tăng bộ đếm tham chiếu cho một đối tượng:

Các bản tham chiếu đầu ra của tập lệnh trên được tính cho

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
02 đầu tiên bên ngoài, sau đó bên trong
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
03, hiển thị mức tăng số lượng tham chiếu không phải một, mà là hai!

Điều đó bởi vì, ngoài chính

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
03, cuộc gọi đến
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
76 bên trong
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
03 cũng nhận được
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
00 như một đối số. Điều này đặt
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
00 trong không gian tên địa phương cho
>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
76, thêm một tham chiếu bổ sung vào
>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
02.

Bằng cách kiểm tra các không gian tên và số lượng tham chiếu bên trong các hàm, bạn có thể thấy rằng các đối số chức năng hoạt động chính xác giống như các bài tập: Python tạo các ràng buộc trong hàm tên tên cục bộ giữa các định danh và đối tượng Python đại diện cho các giá trị đối số. Mỗi ràng buộc này sẽ tăng bộ đếm tham chiếu đối tượng.

Bây giờ bạn có thể thấy Python vượt qua các đối số bằng cách chuyển nhượng!

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
01

Sao chép vượt qua bằng cách tham khảo với Python

  • Sau khi kiểm tra các không gian tên trong phần trước, bạn có thể hỏi tại sao
    >>> def main():
    ...     arg = 4
    ...     square(arg)
    ...     print(arg)
    ...
    >>> def square(n):
    ...     n *= n
    ...
    >>> main()
    4
    
    11 đã được đề cập như một cách để sửa đổi các biến như thể chúng được thông qua bởi tham chiếu:
  • Sử dụng câu lệnh
    >>> def main():
    ...     arg = 4
    ...     square(arg)
    ...     print(arg)
    ...
    >>> def square(n):
    ...     n *= n
    ...
    >>> main()
    4
    
    11 thường lấy đi sự rõ ràng của mã của bạn. Nó có thể tạo ra một số vấn đề, bao gồm cả những vấn đề sau:
  • Các biến miễn phí, dường như không liên quan đến bất cứ điều gì
  • Các chức năng mà không có các đối số rõ ràng cho các biến nói trên

Các chức năng có thể được sử dụng chung với các biến hoặc đối số khác vì chúng dựa vào một biến toàn cầu duy nhất

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
02

Thiếu an toàn sợi chỉ khi sử dụng các biến toàn cầu

Tương phản ví dụ trước với các điều sau đây, trong đó trả về một giá trị rõ ràng:

Tốt hơn nhiều! Bạn tránh tất cả các vấn đề tiềm năng với các biến toàn cầu và bằng cách yêu cầu một đối số, bạn làm cho chức năng của bạn rõ ràng hơn.

Mặc dù không phải là ngôn ngữ ngang qua cũng không phải là ngôn ngữ truyền hình, Python không bị thiếu sót trong vấn đề đó. Tính linh hoạt của nó nhiều hơn là đáp ứng thử thách.

Thực hành tốt nhất: Trả lại và chỉ định lại

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
03

Bạn đã chạm vào việc trả lại các giá trị từ hàm và chỉ định lại chúng thành một biến. Đối với các hàm hoạt động trên một giá trị duy nhất, việc trả về giá trị rõ ràng hơn nhiều so với sử dụng tham chiếu. Hơn nữa, vì Python đã sử dụng các con trỏ phía sau hậu trường, sẽ không có lợi ích hiệu suất bổ sung nào ngay cả khi nó có thể vượt qua các đối số bằng cách tham khảo.

Nhằm mục đích viết các hàm đơn mục đích trả về một giá trị, sau đó (Re) gán giá trị đó cho các biến, như trong ví dụ sau:

Trả lại và gán các giá trị cũng làm cho ý định của bạn rõ ràng và mã của bạn dễ hiểu và kiểm tra hơn.

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
04

Đối với các chức năng hoạt động trên nhiều giá trị, bạn đã thấy rằng Python có khả năng trả lại một bộ giá trị. Bạn thậm chí đã vượt qua sự thanh lịch của int32.tryparse () trong C# nhờ sự linh hoạt của Python!

Nếu bạn cần vận hành trên nhiều giá trị, thì bạn có thể viết các hàm đơn mục đích trả về nhiều giá trị, sau đó (Re) gán các giá trị đó cho các biến. Đây là một ví dụ:

Khi gọi một hàm trả về nhiều giá trị, bạn có thể gán nhiều biến cùng một lúc.

Thực hành tốt nhất: Sử dụng các thuộc tính đối tượng

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
05

Các thuộc tính đối tượng có vị trí riêng của chúng trong chiến lược chuyển nhượng Python. Tham chiếu ngôn ngữ Python sườn cho các câu lệnh gán cho thấy rằng nếu mục tiêu là thuộc tính đối tượng hỗ trợ gán, thì đối tượng sẽ được yêu cầu thực hiện bài tập trên thuộc tính đó. Nếu bạn chuyển đối tượng như một đối số cho một hàm, thì các thuộc tính của nó có thể được sửa đổi tại chỗ.

Viết các chức năng chấp nhận các đối tượng với các thuộc tính, sau đó hoạt động trực tiếp trên các thuộc tính đó, như trong ví dụ sau:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
06

Lưu ý rằng

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
13 cần được viết để hoạt động trực tiếp trên một thuộc tính, sẽ được sửa đổi mà không cần phải gán lại giá trị trả về.

Nó có giá trị lặp lại rằng bạn nên đảm bảo thuộc tính hỗ trợ chuyển nhượng! Ở đây, ví dụ tương tự với

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
14, có thuộc tính chỉ đọc:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
07

Nỗ lực sửa đổi các thuộc tính mà don lồng cho phép sửa đổi dẫn đến

>>> def main():
...     arg = 4
...     square(arg)
...     print(arg)
...
>>> def square(n):
...     n *= n
...
>>> main()
4
15.

Thực hành tốt nhất: Sử dụng từ điển và danh sách

Từ điển trong Python là một loại đối tượng khác với tất cả các loại tích hợp khác. Họ được gọi là loại ánh xạ. Tài liệu Python sườn về các loại ánh xạ cung cấp một số cái nhìn sâu sắc về thuật ngữ:mapping types. Python’s documentation on mapping types provides some insight into the term:mapping types. Python’s documentation on mapping types provides some insight into the term:

Một bản đồ đối tượng ánh xạ các giá trị băm vào các đối tượng tùy ý. Ánh xạ là các đối tượng có thể thay đổi. Hiện tại chỉ có một loại ánh xạ tiêu chuẩn, từ điển. (Nguồn)

Hướng dẫn này không bao gồm cách thực hiện một loại ánh xạ tùy chỉnh, nhưng bạn có thể sao chép thẻ bằng cách tham chiếu bằng từ điển khiêm tốn. Ở đây, một ví dụ sử dụng chức năng hoạt động trực tiếp trên các yếu tố từ điển:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
08

Nỗ lực sửa đổi các thuộc tính mà don lồng cho phép sửa đổi dẫn đến

Thực hành tốt nhất: Sử dụng từ điển và danh sáchsubscriptability and mutability. These characteristics are worthy of a little more explanation, but let’s first take a look at best practices for mimicking pass by reference using Python lists.

Từ điển trong Python là một loại đối tượng khác với tất cả các loại tích hợp khác. Họ được gọi là loại ánh xạ. Tài liệu Python sườn về các loại ánh xạ cung cấp một số cái nhìn sâu sắc về thuật ngữ:mapping types. Python’s documentation on mapping types provides some insight into the term:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
09

Nỗ lực sửa đổi các thuộc tính mà don lồng cho phép sửa đổi dẫn đến

Thực hành tốt nhất: Sử dụng từ điển và danh sáchsubscriptable when a subset of its structure can be accessed by index positions:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
0

Nỗ lực sửa đổi các thuộc tính mà don lồng cho phép sửa đổi dẫn đến

Thực hành tốt nhất: Sử dụng từ điển và danh sáchmutable if its structure can be changed in place rather than requiring reassignment:

>>>

>>> def main():
...     n = 9001
...     print(f"Initial address of n: {id(n)}")
...     increment(n)
...     print(f"  Final address of n: {id(n)}")
...
>>> def increment(x):
...     print(f"Initial address of x: {id(x)}")
...     x += 1
...     print(f"  Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
  Final address of x: 140562586057968
  Final address of n: 140562586057840
1

Nỗ lực sửa đổi các thuộc tính mà don lồng cho phép sửa đổi dẫn đến

Thực hành tốt nhất: Sử dụng từ điển và danh sách

Từ điển trong Python là một loại đối tượng khác với tất cả các loại tích hợp khác. Họ được gọi là loại ánh xạ. Tài liệu Python sườn về các loại ánh xạ cung cấp một số cái nhìn sâu sắc về thuật ngữ:mapping types. Python’s documentation on mapping types provides some insight into the term:

Một bản đồ đối tượng ánh xạ các giá trị băm vào các đối tượng tùy ý. Ánh xạ là các đối tượng có thể thay đổi. Hiện tại chỉ có một loại ánh xạ tiêu chuẩn, từ điển. (Nguồn)

  • Hướng dẫn này không bao gồm cách thực hiện một loại ánh xạ tùy chỉnh, nhưng bạn có thể sao chép thẻ bằng cách tham chiếu bằng từ điển khiêm tốn. Ở đây, một ví dụ sử dụng chức năng hoạt động trực tiếp trên các yếu tố từ điển:assigning values to variables
  • Vì bạn đã chỉ định lại một giá trị cho khóa từ điển, hoạt động trên các phần tử từ điển vẫn là một hình thức gán. Với từ điển, bạn có được tính thực tế bổ sung khi truy cập giá trị sửa đổi thông qua cùng một đối tượng từ điển.passed by assignment in Python
  • Mặc dù danh sách các loại ánh xạ aren, bạn có thể sử dụng chúng theo cách tương tự như từ điển vì hai đặc điểm quan trọng: khả năng đăng ký và khả năng đột biến. Những đặc điểm này đáng để giải thích thêm một chút, nhưng trước tiên, hãy để xem các thực tiễn tốt nhất để bắt chước vượt qua bằng cách tham khảo bằng danh sách Python.subscriptability and mutability. These characteristics are worthy of a little more explanation, but let’s first take a look at best practices for mimicking pass by reference using Python lists.returning values is a best practice for replicating pass by reference
  • Danh sách và bộ có thể thay đổi, cũng như từ điển và các loại ánh xạ khác. Chuỗi và bộ dữ liệu không thể thay đổi. Cố gắng sửa đổi một yếu tố của một đối tượng bất biến sẽ tăng
    >>> def main():
    ...     arg = 4
    ...     square(arg)
    ...     print(arg)
    ...
    >>> def square(n):
    ...     n *= n
    ...
    >>> main()
    4
    
    16.attributes, dictionaries, and lists as alternative best practicesattributes, dictionaries, and lists as alternative best practices

Sự kết luận

Python hoạt động khác với các ngôn ngữ hỗ trợ các đối số truyền theo tham chiếu hoặc theo giá trị. Các đối số chức năng trở thành các biến cục bộ được gán cho từng giá trị được truyền cho hàm. Nhưng điều này không ngăn cản bạn đạt được kết quả tương tự mà bạn mong đợi khi chuyển các đối số bằng cách tham khảo bằng các ngôn ngữ khác.

Trong hướng dẫn này, bạn đã học được:

Cách Python xử lý việc gán các giá trị cho các biến This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Pass by Reference in Python: Best Practices This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Pass by Reference in Python: Best Practices

Làm thế nào để vượt qua các tham số hoạt động?

Tham số truyền liên quan đến việc chuyển các tham số đầu vào vào một mô -đun (một hàm trong C và một hàm và quy trình trong pascal) và nhận các tham số đầu ra trở lại từ mô -đun.Ví dụ, một mô -đun phương trình bậc hai yêu cầu ba tham số được truyền cho nó, đây sẽ là A, B và C.passing input parameters into a module (a function in C and a function and procedure in Pascal) and receiving output parameters back from the module. For example a quadratic equation module requires three parameters to be passed to it, these would be a, b and c.passing input parameters into a module (a function in C and a function and procedure in Pascal) and receiving output parameters back from the module. For example a quadratic equation module requires three parameters to be passed to it, these would be a, b and c.

Tham số đi qua trong Python với ví dụ là gì?

Tham số chuyển sang phía máy chủ tuân theo các quy tắc cho phía máy khách.Một thao tác trả về nhiều giá trị trả về chúng trong một bộ thuật bao gồm một giá trị trả về không khoảng trống, nếu có, theo sau là các tham số ra theo thứ tự khai báo.Một thao tác chỉ trả về một giá trị chỉ đơn giản là trả về chính giá trị.An operation returning multiple values returns them in a tuple consisting of a non- void return value, if any, followed by the out parameters in the order of declaration. An operation returning only one value simply returns the value itself.An operation returning multiple values returns them in a tuple consisting of a non- void return value, if any, followed by the out parameters in the order of declaration. An operation returning only one value simply returns the value itself.

Tham số có cần thiết trong Python không?

Các giá trị cho các tham số không tùy chọn nên được truyền nếu không nó sẽ gây ra lỗi.Giá trị của các đối số mặc định có thể được truyền hoặc bỏ qua.. The value of the default arguments can be either passed or ignored.. The value of the default arguments can be either passed or ignored.