Hướng dẫn can a python function change a variable? - chức năng python có thể thay đổi một biến không?

Lỗi bạn nhận được khi bạn cố gắng chạy mã của mình là:

UnboundLocalError: local variable 'a' referenced before assignment

Mà, trên mặt của nó, có vẻ lạ: sau tất cả, câu lệnh đầu tiên trong mã trên (

def test():
    global a
    a = a + 10
    print(a)
8) là một nhiệm vụ. Vì vậy những gì đang xảy ra?

Trên thực tế, có hai điều riêng biệt xảy ra, và cả hai đều không rõ ràng trừ khi bạn đã biết về chúng.

Trước hết, bạn thực sự có hai biến khác nhau:

  • def test():
        global a
        a = a + 10
        print(a)
    
    9 trong dòng đầu tiên của bạn là một biến toàn cầu (được gọi là vì nó tồn tại trong phạm vi toàn cầu, bên ngoài bất kỳ định nghĩa chức năng nào).

  • def test():
        global a
        a = a + 10
        print(a)
    
    9 trong các dòng khác là một biến cục bộ, có nghĩa là nó chỉ tồn tại bên trong hàm
    a = 15
    
    def test(x):
        x = x + 10
        print(x)
    
    test(a)
    
    1 của bạn.

Hai biến này hoàn toàn không liên quan đến nhau, mặc dù chúng có cùng tên.

Một biến là cục bộ cho một hàm nếu có một câu lệnh gán cho nó bên trong hàm đó - ví dụ: dòng

a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
2 của bạn.

Mặc dù vậy, lỗi vẫn trông lạ - sau tất cả, điều đầu tiên bạn làm trong

a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
1 được gán cho
def test():
    global a
    a = a + 10
    print(a)
9, vậy làm thế nào nó có thể được tham chiếu trước?

Câu trả lời là, trong một tuyên bố gán, Python đánh giá mọi thứ ở phía bên phải của dấu hiệu

a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
5 trước khi gán nó cho tên ở phía bên trái - vì vậy mặc dù bài tập được viết đầu tiên trong mã của bạn,
def test():
    global a
    a = a + 10
    print(a)
9 được tham chiếu trước Ở phía bên phải đó:
a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
7.

Có hai cách bạn có thể có được xung quanh này. Đầu tiên là nói với Python rằng bạn thực sự muốn

def test():
    global a
    a = a + 10
    print(a)
9 bên trong
a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
1 giống nhau
def test():
    global a
    a = a + 10
    print(a)
9 trong phạm vi toàn cầu:

def test():
    global a
    a = a + 10
    print(a)

Điều này sẽ hoạt động, nhưng đó là một cách khá tệ để viết các chương trình. Việc thay đổi các biến toàn cầu bên trong các chức năng khó quản lý thực sự nhanh chóng, bởi vì bạn thường có nhiều chức năng và không ai trong số chúng có thể chắc chắn rằng một trong số đó không gây rối với biến toàn cầu theo một cách nào đó mà họ không mong đợi.

Một cách tốt hơn là chuyển các biến làm đối số cho các hàm, như thế này:

a = 15

def test(x):
    x = x + 10
    print(x)

test(a)

Lưu ý rằng tên không phải giống nhau - định nghĩa mới của bạn về

a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
1 chỉ nói rằng nó chấp nhận một giá trị, và sau đó làm điều gì đó với nó. Bạn có thể vượt qua bất cứ thứ gì bạn thích - nó có thể là
def test():
    global a
    a = a + 10
    print(a)
9, hoặc số
>>> a = 15
>>> test(a)
25
>>> a
15
3, hoặc một cái gì đó khác. Trên thực tế, mã của bạn sẽ luôn dễ hiểu hơn nếu bạn cố gắng tránh có các biến có cùng tên trong các phạm vi khác nhau.

Nếu bạn chơi với mã ở trên, bạn sẽ nhận thấy điều gì đó thú vị:

>>> a = 15
>>> test(a)
25
>>> a
15

Mạnh

def test():
    global a
    a = a + 10
    print(a)
9 không thay đổi! Đó là bởi vì mặc dù bạn đã chuyển nó vào
a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
1 và nó được gán cho
>>> a = 15
>>> test(a)
25
>>> a
15
6, nhưng sau đó
>>> a = 15
>>> test(a)
25
>>> a
15
6 đã thay đổi, chỉ để lại
def test():
    global a
    a = a + 10
    print(a)
9 ban đầu.

Nếu bạn muốn thực sự thay đổi

def test():
    global a
    a = a + 10
    print(a)
9, bạn cần trả lại
>>> a = 15
>>> test(a)
25
>>> a
15
6 đã sửa đổi của mình từ chức năng, sau đó chỉ định lại nó trở lại
def test():
    global a
    a = a + 10
    print(a)
9 ở bên ngoài:

>>> a = 15
>>> 
>>> def test(x):
...     x = x + 10
...     print(x)
...     return x
... 
>>> a = test(a)
25
>>> a
25

Các biến toàn cầu và cục bộ cùng tên

Kiểm tra ví dụ này,

Quảng cáo

total = 100 

def func1(): 
   total = 15 

print('Total = ', total) 

func1() 

print('Total = ', total)
Output:
Total = 100 
Total = 100

Ở đây 'Tổng số' là một biến toàn cầu và hàm func () có một biến cục bộ cùng tên. Theo mặc định, một hàm ưu tiên cho biến cục bộ hơn biến toàn cầu nếu cả hai đều có cùng tên. Do đó, trong mã trên khi chúng tôi sửa đổi biến 'tổng' bên trong hàm thì nó không được phản ánh bên ngoài hàm. Bởi vì bên trong hàm func () Tổng biến được coi là biến cục bộ.total' is a global variable and func() function has a local variable with same name. By default a function gives preference to
local variable over global variable if both are of same name. Therefore in above code when we modified 'total' variable inside the function then it was not reflected outside the function. Because inside function func() total variable is treated as local variable.

Nhưng điều gì sẽ xảy ra nếu muốn truy cập biến toàn cầu bên trong một hàm có biến cục bộ cùng tên?

Sử dụng từ khóa toàn cầu † để sửa đổi biến toàn cầu bên trong một chức năng

Nếu chức năng của bạn có một biến cục bộ có cùng tên với biến toàn cầu và bạn muốn sửa đổi chức năng biến toàn cầu bên trong thì hãy sử dụng từ khóa 'toàn cầu' trước tên biến khi bắt đầu chức năng, tức là.

global total

Nó sẽ làm cho chức năng tham khảo tổng số biến toàn cầu bất cứ khi nào được truy cập. Kiểm tra ví dụ này,

total = 100
def func():
    # refer to global variable 'total' inside function
    global total
    if total > 10:
        total = 15

print('Total = ', total)
func()
print('Total = ', total)

Output:

def test():
    global a
    a = a + 10
    print(a)
0

Như bạn có thể thấy sửa đổi được thực hiện cho tổng số biến toàn cầu hiện có thể nhìn thấy bên ngoài chức năng.

Khi chúng tôi sử dụng từ khóa toàn cầu với một biến bên trong hàm thì biến cục bộ sẽ được ẩn. Nhưng điều gì sẽ xảy ra nếu chúng ta muốn giữ Bot là biến cục bộ & toàn cầu với giống nhau và sửa đổi cả hai trong chức năng? Hãy xem làm thế nào để làm điều đó,

Sử dụng Globals () để truy cập các biến toàn cầu bên trong hàm

Vì các từ khóa 'toàn cầu' ẩn biến cục bộ có cùng tên, vì vậy để truy cập cả biến cục bộ và toàn cầu bên trong một hàm, có một cách khác, tức là toàn cầu () Sử dụng nó để truy cập / sửa đổi biến toàn cầu mà không cần sử dụng từ khóa 'toàn cầu' I, e.'global' keywords hide the local variable with same name, so to access both the local & global variable inside a function there is an another way i.e. global() function.
globals() returns a dictionary of elements in current module and we can use it to access / modify the global variable without using 'global' keyword i,e.

def test():
    global a
    a = a + 10
    print(a)
1

Đầu ra:

def test():
    global a
    a = a + 10
    print(a)
2

Như bạn có thể thấy rằng chúng tôi có biến cục bộ và biến toàn cầu với cùng tên, tức là tổng số và chúng tôi đã sửa đổi cả hai bên trong hàm. Bằng cách sử dụng từ điển được trả về bởi Globals () để tham khảo biến toàn cầu thay vì từ khóa 'toàn cầu'. Nó sẽ không ẩn biến cục bộ bên trong hàm.globals() to refer global variable instead of keyword 'global'. It will not hide local variable inside the function.

Xử lý lỗi không liên lạc

Nếu chúng ta cố gắng truy cập một biến toàn cầu với từ khóa 'toàn cầu' hoặc toàn cầu () bên trong một hàm, tức là.

def test():
    global a
    a = a + 10
    print(a)
3

Nó sẽ ném một lỗi như thế này,

def test():
    global a
    a = a + 10
    print(a)
4

Để ngăn chặn lỗi này, chúng tôi cần sử dụng từ khóa 'toàn cầu' hoặc hàm toàn cầu (), tức là.

def test():
    global a
    a = a + 10
    print(a)
5

Ví dụ hoàn chỉnh về biến toàn cầu và toàn cầu () trong Python

def test():
    global a
    a = a + 10
    print(a)
6

Output:

def test():
    global a
    a = a + 10
    print(a)
7

Một chức năng có thể thay đổi một biến?

Các chức năng có thể truy cập các biến toàn cầu và sửa đổi chúng.Sửa đổi các biến toàn cầu trong một hàm được coi là thực hành lập trình kém.Tốt hơn là gửi một biến trong một tham số (hoặc có nó được trả về trong câu lệnh 'return').. Modifying global variables in a function is considered poor programming practice. It is better to send a variable in as a parameter (or have it be returned in the 'return' statement).

Một chức năng có thể thay đổi một python biến toàn cầu?

Như những người khác đã lưu ý, bạn cần khai báo một biến toàn cầu trong một hàm khi bạn muốn chức năng đó có thể sửa đổi biến toàn cầu.Nếu bạn chỉ muốn truy cập nó, thì bạn không cần toàn cầu.

Một hàm có thể trả về một python biến?

Các hàm Python có thể trả về nhiều biến.Các biến này có thể được lưu trữ trực tiếp trong các biến.Một hàm không bắt buộc để trả về một biến, nó có thể trả về 0, một, hai hoặc nhiều biến.Đây là một thuộc tính duy nhất của Python, các ngôn ngữ lập trình khác như C ++ hoặc Java không hỗ trợ điều này theo mặc định.. These variables can be stored in variables directly. A function is not required to return a variable, it can return zero, one, two or more variables. This is a unique property of Python, other programming languages such as C++ or Java do not support this by default.