Các hàm Python gọi bằng tham chiếu


82

Trong một số ngôn ngữ, bạn có thể chuyển một tham số theo tham chiếu hoặc giá trị bằng cách sử dụng một từ dành riêng đặc biệt như ref hoặc val . Khi bạn truyền một tham số cho một hàm Python, nó không bao giờ thay đổi giá trị của tham số khi rời khỏi hàm. Cách duy nhất để làm điều này là sử dụng từ dành riêng toàn cục (hoặc theo cách hiểu của tôi hiện tại).

Ví dụ 1:

k = 2

def foo (n):
     n = n * n     #clarity regarding comment below
     square = n
     return square

j = foo(k)
print j
print k

Sẽ hiển thị

>>4
>>2

hiển thị k là không thay đổi

Trong ví dụ này, biến n không bao giờ thay đổi

Ví dụ 2:

n = 0
def foo():
    global n
    n = n * n
    return n

Trong ví dụ này, biến n được thay đổi

Có cách nào trong Python để gọi một hàm và cho Python biết rằng tham sốgiá trị hoặc tham số tham chiếu thay vì sử dụng toàn cục không?

Thứ hai, trong các kỳ thi Cambridge cấp độ A, giờ đây họ nói rằng một hàm trả về một giá trị duy nhất trong khi một thủ tục trả về nhiều hơn một giá trị. Tôi đã được dạy một hàm có câu lệnh trả về và thủ tục thì không, trong suốt những năm 80. Tại sao điều này bây giờ không chính xác?


5
Các nguồn tốt nhất mà tôi đã tìm thấy cho mô hình kêu gọi sự hiểu biết trăn là bài viết này trên effbot: effbot.org/zone/call-by-object.htm
Wilduck

1
bạn nên đọc về các biến Python, các đối tượng có thể thay đổi và không thể thay đổi. Cũng trong ví dụ đầu tiên của bạn tại sao sẽ nđược thay đổi, bạn đang sử dụng một biến mới squaređể lưu trữ kết quả tính toán của mình.
Facundo Casco

6
Vui lòng không đăng hai câu hỏi không liên quan trong một. Định nghĩa của hàm so với thủ tục là một vấn đề của định nghĩa, và có vẻ như định nghĩa của bạn thiên về Pascal. Không có cái gọi là thủ tục trong biệt ngữ Python.
Fred Foo

2
Ngoài ra, hãy xem câu trả lời StackOverflow trước này. stackoverflow.com/a/10262945/173292 Nó giải thích cuộc gọi theo mô hình tham chiếu đối tượng khá trực quan.
Wilduck

1
Xem thêm những câu hỏi SO này giải thích rất hữu ích: làm thế nào để tôi vượt qua một biến bằng cách tham khảo
Michael Ohlrogge

Câu trả lời:


78

Bạn không thể thay đổi một đối tượng không thể thay đổi, như strhoặc tuple, bên trong một hàm trong Python, nhưng bạn có thể làm những việc như:

def foo(y):
  y[0] = y[0]**2

x = [5]
foo(x)
print x[0]  # prints 25

Tuy nhiên, đó là một cách kỳ lạ, trừ khi bạn cần phải luôn cân bằng các phần tử nhất định trong một mảng.

Lưu ý rằng trong Python, bạn cũng có thể trả về nhiều giá trị, làm cho một số trường hợp sử dụng để chuyển qua tham chiếu ít quan trọng hơn:

def foo(x, y):
   return x**2, y**2

a = 2
b = 3
a, b = foo(a, b)  # a == 4; b == 9

Khi bạn trả về các giá trị như vậy, chúng sẽ được trả về dưới dạng một Tuple và lần lượt được giải nén.

chỉnh sửa: Một cách khác để nghĩ về điều này là, mặc dù bạn không thể chuyển rõ ràng các biến bằng tham chiếu trong Python, nhưng bạn có thể sửa đổi các thuộc tính của các đối tượng đã được chuyển vào. Trong ví dụ của tôi (và những người khác), bạn có thể sửa đổi các thành viên của danh sách đã được chuyển vào. Tuy nhiên, bạn sẽ không thể gán lại hoàn toàn biến đã chuyển vào. Ví dụ: hãy xem hai đoạn mã sau trông giống như chúng có thể làm điều gì đó tương tự, nhưng cuối cùng lại cho kết quả khác nhau:

def clear_a(x):
  x = []

def clear_b(x):
  while x: x.pop()

z = [1,2,3]
clear_a(z) # z will not be changed
clear_b(z) # z will be emptied

2
Sẽ rất hữu ích khi xem kết quả của các chương trình. Ví dụ: 'print x [0]' có trả về 25 không? (Có nó, nhưng điều đó sẽ được hiển thị.)
Ray Salemi

11
@alexey clear_ađược cung cấp một tham chiếu đến zvà lưu trữ tham chiếu đó trong x. Sau đó, nó ngay lập tức thay đổi xđể tham chiếu đến một mảng khác. zMảng ban đầu bị lãng quên trong phạm vi clear_a, nhưng không thực sự thay đổi. Nó tiếp tục không thay đổi khi quay trở lại phạm vi toàn cầu. Ngược lại với clear_bnó mà có một tham chiếu đến zvà sau đó hoạt động trực tiếp trên nó, mà không bao giờ tạo một mảng mới hoặc cách khác trỏ xvà một cái gì đó khác.
dave mankoff

cảm ơn dave! Tôi cố gắng "tạo ra một mảng mới" trong clear_b, y = x, y: y.pop()và sau đó được gọi clear_b(z), z vẫn đã làm trống ... Vì vậy, chúng ta cần một cái gì đó như y = list(x)để tạo ra một bản sao của x (danh sách (x) đã giải thích ở đây )
Alexey

run_thread = [True] t= threading.Thread(target=module2.some_method, \ args=(11,1,run_thread)) --do something - and when you want to sop run_thread[0] =False
Alex Punnen

Không có kiểu nguyên thủy trong Python, không giống như Java. Tất cả các loại đối tượng thể hiện.
Marco Sulla

181

Về cơ bản có ba loại 'lệnh gọi hàm':

  • Chuyển theo giá trị
  • Chuyển qua tài liệu tham khảo
  • Chuyển qua tham chiếu đối tượng

Python là một ngôn ngữ lập trình PASS-BY-OBJECT-REFERENCE.

Đầu tiên, điều quan trọng là phải hiểu rằng một biến và giá trị của biến (đối tượng) là hai thứ riêng biệt. Biến 'trỏ tới' đối tượng. Biến không phải là đối tượng. Lần nữa:

BIẾN SỐ KHÔNG PHẢI LÀ ĐỐI TƯỢNG

Ví dụ: trong dòng mã sau:

>>> x = []

[]là danh sách trống, xlà một biến trỏ đến danh sách trống, nhưng xbản thân nó không phải là danh sách trống.

Coi biến ( x, trong trường hợp trên) là một hộp và 'giá trị' của biến ( []) là đối tượng bên trong hộp.

PASS THEO ĐỐI TƯỢNG THAM KHẢO (Trường hợp trong python):

Ở đây, "Tham chiếu đối tượng được chuyển theo giá trị."

def append_one(li):
    li.append(1)
x = [0]
append_one(x)
print x

Ở đây, câu lệnh x = [0]tạo một biến x(hộp) hướng tới đối tượng [0].

Trên hàm đang được gọi, một hộp mới liđược tạo. Nội dung của lilà CÙNG với nội dung của hộp x. Cả hai hộp đều chứa cùng một đối tượng. Có nghĩa là, cả hai biến đều trỏ đến cùng một đối tượng trong bộ nhớ. Do đó, bất kỳ thay đổi nào đối với đối tượng được trỏ tới licũng sẽ được phản ánh bởi đối tượng được trỏ tới x.

Kết luận, đầu ra của chương trình trên sẽ là:

[0, 1]

Ghi chú:

Nếu biến liđược gán lại trong hàm, thì lisẽ trỏ đến một đối tượng riêng biệt trong bộ nhớ. xtuy nhiên, sẽ tiếp tục trỏ đến cùng một đối tượng trong bộ nhớ mà nó đã trỏ đến trước đó.

Thí dụ:

def append_one(li):
    li = [0, 1]
x = [0]
append_one(x)
print x

Đầu ra của chương trình sẽ là:

[0]

XEM THEO THAM KHẢO:

Hộp từ hàm đang gọi được chuyển cho hàm được gọi. Ngầm nhiên, nội dung của hộp (giá trị của biến) được chuyển cho hàm được gọi. Do đó, bất kỳ thay đổi nào đối với nội dung của hộp trong hàm được gọi sẽ được phản ánh trong hàm đang gọi.

XÓA THEO GIÁ TRỊ:

Một hộp mới được tạo trong hàm được gọi và các bản sao nội dung của hộp từ hàm gọi được lưu trữ vào các hộp mới.

Hi vọng điêu nay co ich.


3
Bạn có thể đưa ra các ví dụ về "chuyển theo tham chiếu" và "chuyển theo giá trị" như bạn đã làm đối với "chuyển theo tham chiếu đối tượng".
TJain

@TJain Truyền theo tham chiếu và chuyển theo giá trị có thể được nhìn thấy trong C ++. Câu trả lời này đưa ra một lời giải thích tốt: stackoverflow.com/a/430958/5076583
Shobhit Verma

3
Tôi vẫn không hiểu điều này khác với tham chiếu qua đường như thế nào. Câu trả lời này rất cần một ví dụ về cách mã giả giống hệt nhau sẽ tạo ra các đầu ra khác nhau cho cả 3 mô hình. Việc liên kết với một câu trả lời khác chỉ giải thích sự khác biệt giữa giá trị chuyển qua tham chiếu và giá trị chuyển qua không hữu ích.
Jess Riedel

Không đơn giản hơn khi nói rằng "tất cả các biến trong Python là con trỏ " và "tất cả các biến được gán cho các tham số trong một lệnh gọi hàm đều được gán cho con trỏ mới?". Nếu bạn nhận ra điều này, bạn sẽ thấy rằng Python giống như Java: nó chỉ đơn giản là luôn chuyển con trỏ theo giá trị . Xem câu trả lời của Kirk Strauser
Marco Sulla

26

Được rồi, tôi sẽ bắt tay vào việc này. Python chuyển theo tham chiếu đối tượng, khác với những gì bạn thường nghĩ là "theo tham chiếu" hoặc "theo giá trị". Lấy ví dụ sau:

def foo(x):
    print x

bar = 'some value'
foo(bar)

Vì vậy, bạn đang tạo một đối tượng chuỗi có giá trị 'một số giá trị' và "liên kết" nó với một biến có tên bar. Trong C, điều đó sẽ tương tự như bartrở thành một con trỏ đến 'một số giá trị'.

Khi bạn gọi foo(bar), bạn không tự vượt qua bar. Bạn đang chuyển bargiá trị của 's: một con trỏ đến' giá trị nào đó '. Tại thời điểm đó, có hai "con trỏ" đến cùng một đối tượng chuỗi.

Bây giờ so sánh với:

def foo(x):
    x = 'another value'
    print x

bar = 'some value'
foo(bar)

Đây là nơi mà sự khác biệt nằm. Trong dòng:

x = 'another value'

bạn không thực sự thay đổi nội dung của x. Trong thực tế, điều đó thậm chí không thể. Thay vào đó, bạn đang tạo một đối tượng chuỗi mới với giá trị 'giá trị khác'. Toán tử gán đó? Nó không nói "ghi đè thứ xđang trỏ đến bằng giá trị mới". Nó nói "cập nhật xđể trỏ vào đối tượng mới thay thế". Sau dòng đó, có hai đối tượng chuỗi: 'một số giá trị' (với việc bartrỏ vào nó) và 'một giá trị khác' (với việc xtrỏ vào nó).

Đây không phải là vụng về. Khi bạn hiểu nó hoạt động như thế nào, đó là một hệ thống hiệu quả, trang nhã.


3
Nhưng nếu tôi muốn hàm thay đổi nội dung của biến của tôi thì sao? Tôi hiểu rằng không có cách nào để làm điều này?
aquirdturtle

1
Bạn có thể thay đổi đối tượng mà tên đang trỏ đến, ví dụ bằng cách thêm vào danh sách, nếu đối tượng đó có thể thay đổi được. Không có ngữ nghĩa Python nào để nói "thay đổi không gian tên của phạm vi đã gọi tôi để tên trong danh sách đối số của tôi bây giờ trỏ đến một cái gì đó khác với khi nó gọi tôi".
Kirk Strauser

2
Hiệu quả những gì tôi đang hỏi là nếu có một cách đơn giản để khiến python không tạo một con trỏ mới cho cùng một đối tượng mà thay vào đó sử dụng con trỏ gốc. Tôi hiểu rằng không có cách nào để làm điều này. Tôi lấy nó từ các câu trả lời khác rằng công việc bình thường để đạt được những gì truyền qua tham chiếu chỉ là trả về nhiều tham số hơn. nếu đúng như vậy, tôi thấy một số hợp lệ trong lập luận rằng a, b, c, d, e = foo (a, b, c, d, e) hơi khó hiểu hơn là chỉ foo (a, b, c, d, e).
aquirdturtle

2
@aquirdturtle Điều này không có gì phải làm bởi thực tế là một con trỏ mới đã được tạo. Bạn phải trả về một đối tượng mới vì strings, tuples và các đối tượng khác là bất biến . Nếu bạn truyền một đối tượng có thể thay đổi, chẳng hạn như a list, bạn có thể thay đổi nó bên trong hàm mà không cần trả lại nó, bởi vì tất cả các tham số hàm đều là con trỏ đến cùng các đối tượng mà bạn đã truyền.
Marco Sulla

23

Hy vọng mô tả sau đây sẽ tổng hợp tốt:

Có hai điều cần xem xét ở đây - biến và đối tượng.

  1. Nếu bạn đang chuyển một biến, thì nó sẽ chuyển theo giá trị, có nghĩa là những thay đổi được thực hiện đối với biến trong hàm là cục bộ của hàm đó và do đó sẽ không được phản ánh trên toàn cục. Đây là một hành vi giống như chữ 'C'.

Thí dụ:

def changeval( myvar ):
   myvar = 20; 
   print "values inside the function: ", myvar
   return

myvar = 10;
changeval( myvar );
print "values outside the function: ", myvar

O / P:

values inside the function:  20 
values outside the function:  10
  1. Nếu bạn đang chuyển các biến được đóng gói bên trong một đối tượng có thể thay đổi, chẳng hạn như một danh sách, thì những thay đổi được thực hiện đối với đối tượng được phản ánh trên toàn cục miễn là đối tượng không được gán lại.

Thí dụ:

def changelist( mylist ):
   mylist2=['a'];
   mylist.append(mylist2);
   print "values inside the function: ", mylist
   return

mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist

O / P:

values inside the function:  [1, 2, 3, ['a']]
values outside the function:  [1, 2, 3, ['a']]
  1. Bây giờ hãy xem xét trường hợp đối tượng được gán lại. Trong trường hợp này, đối tượng đề cập đến một vị trí bộ nhớ mới là vị trí cục bộ cho chức năng mà điều này xảy ra và do đó không được phản ánh trên toàn cục.

Thí dụ:

def changelist( mylist ):
   mylist=['a'];
   print "values inside the function: ", mylist
   return

mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist

O / P:

values inside the function:  ['a']
values outside the function:  [1, 2, 3]

2
Đây là bản tóm tắt tốt nhất! ^^^ TÓM TẮT HAY NHẤT TẠI ĐÂY ^^^ mọi người cùng đọc câu trả lời này nhé! 1. vượt qua các biến đơn giản 2. tham chiếu đối tượng vượt qua được sửa đổi 3. tham chiếu đối tượng vượt qua được bố trí chức năng
gaoithe

3
Câu trả lời này rất bối rối. Python không truyền các loại giá trị khác nhau theo cách khác nhau: tất cả các đối số hàm trong Python đều nhận giá trị của chúng bằng cách gán và hoạt động giống hệt như cách mà phép gán hoạt động ở bất kỳ nơi nào khác trong ngôn ngữ. ("Mặc dù cách đó có thể không rõ ràng lúc đầu trừ khi bạn là người Hà Lan.")
Daniel Pryden

9

Python không phải là giá trị truyền cũng như tham chiếu chuyển qua. Nó có nhiều "tham chiếu đối tượng được truyền theo giá trị" như được mô tả ở đây :

  1. Đây là lý do tại sao nó không phải là giá trị chuyển tiếp. Bởi vì

    def append(list):
        list.append(1)
    
    list = [0]
    reassign(list)
    append(list)
    

trả về [0,1] cho thấy rằng một số loại tham chiếu đã được chuyển rõ ràng dưới dạng giá trị chuyển qua không cho phép một hàm thay đổi phạm vi chính .

Hình như là tham chiếu chuyển qua vậy, hu? Không.

  1. Đây là lý do tại sao nó không phải là tham chiếu qua lại. Bởi vì

    def reassign(list):
      list = [0, 1]
    
    list = [0]
    reassign(list)
    print list
    

trả về [0] cho thấy rằng tham chiếu ban đầu đã bị hủy khi danh sách được gán lại. tham chiếu chuyển qua sẽ trả về [0,1] .

Để biết thêm thông tin, hãy xem tại đây :

Nếu bạn muốn hàm của mình không thao tác bên ngoài phạm vi, bạn cần tạo một bản sao của các tham số đầu vào để tạo một đối tượng mới.

from copy import copy

def append(list):
  list2 = copy(list)
  list2.append(1)
  print list2

list = [0]
append(list)
print list

4

Về mặt kỹ thuật, python không chuyển đối số theo giá trị: tất cả đều bằng tham chiếu. Nhưng ... vì python có hai loại đối tượng: bất biến và có thể thay đổi, đây là những gì sẽ xảy ra:

  • Các đối số bất biến được truyền một cách hiệu quả bởi giá trị : chuỗi, số nguyên, tuple là tất cả các kiểu đối tượng bất biến. Mặc dù về mặt kỹ thuật, chúng được "truyền bằng tham chiếu" (giống như tất cả các tham số), vì bạn không thể thay đổi chúng tại chỗ bên trong hàm, nó trông / hoạt động như thể được truyền theo giá trị.

  • Các đối số có thể thay đổi được chuyển qua tham chiếu một cách hiệu quả : danh sách hoặc từ điển được chuyển bởi con trỏ của nó. Bất kỳ thay đổi tại chỗ nào bên trong hàm như (append hoặc del) sẽ ảnh hưởng đến đối tượng ban đầu.

Đây là cách Python được thiết kế: không có bản sao và tất cả đều được chuyển qua tham chiếu. Bạn có thể chuyển một bản sao một cách rõ ràng.

def sort(array):
    # do sort
    return array

data = [1, 2, 3]
sort(data[:]) # here you passed a copy

Điểm cuối cùng tôi muốn đề cập đó là một hàm có phạm vi riêng của nó.

def do_any_stuff_to_these_objects(a, b): 
    a = a * 2 
    del b['last_name']

number = 1 # immutable
hashmap = {'first_name' : 'john', 'last_name': 'legend'} # mutable
do_any_stuff_to_these_objects(number, hashmap) 
print(number) # 1 , oh  it should be 2 ! no a is changed inisde the function scope
print(hashmap) # {'first_name': 'john'}

1
"Các đối số bất biến được truyền một cách hiệu quả bởi giá trị: chuỗi, số nguyên, tuple đều được truyền bằng tham chiếu" câu này tự mâu thuẫn
eral

@eral, nếu bạn hiểu ngữ cảnh đầy đủ, nó không mâu thuẫn với chính nó. Tôi đã chỉnh sửa nó để làm cho điều này rõ ràng hơn.
Watki02

2

Vì vậy, đây là một điểm hơi tinh tế, bởi vì trong khi Python chỉ chuyển các biến theo giá trị, mọi biến trong Python đều là một tham chiếu. Nếu bạn muốn có thể thay đổi các giá trị của mình bằng một lệnh gọi hàm, những gì bạn cần là một đối tượng có thể thay đổi. Ví dụ:

l = [0]

def set_3(x):
    x[0] = 3

set_3(l)
print(l[0])

Trong đoạn mã trên, hàm sửa đổi nội dung của một đối tượng Danh sách (có thể thay đổi), và do đó kết quả đầu ra là 3 thay vì 0.

Tôi viết câu trả lời này chỉ để minh họa 'theo giá trị' có nghĩa là gì trong Python. Đoạn mã trên là kiểu xấu và nếu bạn thực sự muốn thay đổi các giá trị của mình, bạn nên viết một lớp và gọi các phương thức trong lớp đó, như MPX gợi ý.


điều này trả lời một nửa câu hỏi, vậy làm thế nào tôi sẽ viết cùng một hàm set_3 (x) để nó không thay đổi giá trị của l nhưng trả về một danh sách mới đã được thay đổi?
Timothy Lawman

Chỉ cần tạo một danh sách mới và sửa đổi nó:y = [a for a in x]; y[0] = 3; return y
Isaac

toàn bộ mọi thứ liên quan đến danh sách và sao chép danh sách theo một số cách để trả lời, nhưng làm thế nào tôi có thể làm điều đó mà không cần phải chuyển đổi một số nguyên thành một danh sách hay đây là cách tốt nhất mà chúng tôi có?
Timothy Lawman

Bạn không thể sửa đổi một đối số nguyên thủy như một int. Bạn phải đặt nó trong một số loại vật chứa. Ví dụ của tôi đưa nó vào một danh sách. Bạn cũng có thể đặt nó trong một lớp học hoặc một từ điển. Tuy nhiên, thực sự thì bạn chỉ nên gán lại nó bên ngoài một chức năng với một cái gì đó như x = foo(x).
Isaac

0

Câu trả lời được đưa ra là

def set_4(x):
   y = []
   for i in x:
       y.append(i)
   y[0] = 4
   return y

l = [0]

def set_3(x):
     x[0] = 3

set_3(l)
print(l[0])

đó là câu trả lời tốt nhất cho đến nay so với những gì nó nói trong câu hỏi. Tuy nhiên, nó có vẻ là một cách rất vụng về so với VB hoặc Pascal. Nó có phải là phương pháp tốt nhất mà chúng ta có?

Nó không chỉ vụng về mà còn liên quan đến việc thay đổi tham số ban đầu theo một cách thủ công nào đó, ví dụ như bằng cách thay đổi tham số ban đầu thành một danh sách: hoặc sao chép nó vào một danh sách khác thay vì chỉ nói: "sử dụng tham số này làm giá trị" hoặc "sử dụng tham số này như một tài liệu tham khảo ”. Có thể câu trả lời đơn giản là không có từ dành riêng cho điều này nhưng đây là những cách giải quyết tuyệt vời?


0

Hãy xem xét rằng biến là một hộp và giá trị mà nó trỏ tới là "thứ" bên trong hộp:

1. Truyền qua tham chiếu: hàm chia sẻ cùng một hộp và do đó thứ bên trong cũng có.

2. Truyền theo giá trị: hàm tạo một hộp mới, một bản sao của hộp cũ, bao gồm một bản sao của bất cứ thứ gì bên trong nó. Ví dụ. Java - các hàm tạo một bản sao của hộp và thứ bên trong hộp có thể là: một nguyên thủy / một tham chiếu đến một đối tượng. (lưu ý rằng tham chiếu được sao chép trong hộp mới và cả hai tham chiếu gốc vẫn trỏ đến cùng một đối tượng, ở đây tham chiếu LÀ thứ bên trong hộp, không phải đối tượng mà nó đang trỏ tới)

3. Truyền qua đối tượng-tham chiếu : hàm tạo một hộp, nhưng nó bao quanh cùng một thứ mà hộp ban đầu đã bao quanh. Vì vậy, trong Python :

a) nếu thứ bên trong hộp nói trên có thể thay đổi được , các thay đổi được thực hiện sẽ phản ánh trở lại trong hộp ban đầu (ví dụ: danh sách)

b) nếu thứ là không thay đổi (như chuỗi python và kiểu số), thì hộp bên trong hàm sẽ chứa thứ giống như vậy CHO ĐẾN KHI bạn cố gắng thay đổi giá trị của nó. Sau khi thay đổi, thứ trong hộp của chức năng là một thứ hoàn toàn mới so với cái ban đầu. Do đó, id () cho hộp đó bây giờ sẽ cung cấp danh tính của thứ mới mà nó bao quanh .


0
class demoClass:
    x = 4
    y = 3
foo1 = demoClass()
foo1.x = 2
foo2 = demoClass()
foo2.y = 5
def mySquare(myObj):
    myObj.x = myObj.x**2
    myObj.y = myObj.y**2
print('foo1.x =', foo1.x)
print('foo1.y =', foo1.y)
print('foo2.x =', foo2.x)
print('foo2.y =', foo2.y)
mySquare(foo1)
mySquare(foo2)
print('After square:')
print('foo1.x =', foo1.x)
print('foo1.y =', foo1.y)
print('foo2.x =', foo2.x)
print('foo2.y =', foo2.y)

-2

Trong Python, việc chuyển theo tham chiếu hoặc theo giá trị liên quan đến những đối tượng thực tế mà bạn đang truyền. Do đó, bạn đang chuyển một con trỏ đến hàm và bạn có thể sửa đổi đối tượng (danh sách) trong thân hàm.

Khi bạn đang truyền một chuỗi, việc truyền này được thực hiện bởi giá trị, vì vậy một đối tượng chuỗi mới đang được tạo và khi hàm kết thúc, nó sẽ bị hủy. Vì vậy, tất cả đều liên quan đến các đối tượng có thể thay đổi và bất biến.


1
Điều đó hoàn toàn không chính xác. Python luôn đi qua "tham chiếu đối tượng" (khác với tham chiếu biến).
Kirk Strauser vào

i có nghĩa là các đối tượng có thể thay đổi tương tự - vượt qua bởi các đối tượng tham khảo và không thay đổi - vượt qua bởi value.It là hoàn hảo có giá trị gì tôi saying.You lẽ không bắt được những gì tôi đang nói
jkalivas

1
Tôi đã bắt được nó và nó sai. Nó không liên quan gì đến việc một đối tượng có thể thay đổi hoặc bất biến; nó luôn được thực hiện theo cùng một cách.
Kirk Strauser,

-2

Python đã được gọi bằng ref ..

hãy lấy ví dụ:

  def foo(var):
      print(hex(id(var)))


  x = 1 # any value
  print(hex(id(x))) # I think the id() give the ref... 
  foo(x)

OutPut

  0x50d43700 #with you might give another hex number deppend on your memory 
  0x50d43700

Không, đó là không đúng sự thậtdef foo(var): print(id(var)) var = 1234 print(id(var)) x = 123 print(id(x)) # I think the id() give the ref... foo(x) print(id(x))
zohaib Ijaz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.