Python giữ biến giữa các lần gọi hàm

Cách Python sử dụng các biến toàn cục và biến cục bộ là maverick. Trong khi ở nhiều hoặc hầu hết các ngôn ngữ lập trình khác, các biến được coi là toàn cầu nếu không được khai báo khác, Python xử lý các biến theo cách khác. Chúng là cục bộ, nếu không được khai báo khác. Lý do đằng sau cách tiếp cận này là các biến toàn cầu nói chung là thông lệ không tốt và nên tránh. Trong hầu hết các trường hợp khi bạn muốn sử dụng biến toàn cục, tốt hơn là sử dụng tham số để nhận giá trị vào hàm hoặc trả về giá trị để lấy giá trị ra. Giống như trong nhiều cấu trúc chương trình khác, Python cũng áp đặt thói quen lập trình tốt theo thiết kế

Vì vậy, khi bạn xác định các biến bên trong một định nghĩa hàm, theo mặc định, chúng là cục bộ của hàm này. Nghĩa là, bất cứ điều gì bạn làm với một biến như vậy trong phần thân của hàm sẽ không ảnh hưởng đến các biến khác bên ngoài hàm, ngay cả khi chúng có cùng tên. Nói cách khác, thân hàm là phạm vi của một biến như vậy, tôi. e. bối cảnh kèm theo nơi tên này được liên kết với các giá trị của nó

Tất cả các biến đều có phạm vi của khối, nơi chúng được khai báo và định nghĩa. Chúng chỉ có thể được sử dụng sau thời điểm khai báo

Chỉ để làm cho mọi thứ rõ ràng. Các biến không nhất thiết phải và không thể được khai báo theo cách chúng được khai báo trong các ngôn ngữ lập trình như Java hoặc C. Các biến trong Python được khai báo ngầm bằng cách định nghĩa chúng, i. e. lần đầu tiên bạn gán giá trị cho một biến, biến này được khai báo và tự động có kiểu dữ liệu của đối tượng được gán cho nó. Nếu bạn gặp khó khăn trong việc hiểu điều này, vui lòng tham khảo chương của chúng tôi về các kiểu dữ liệu và biến, xem các liên kết ở bên trái

Biến toàn cục và biến cục bộ trong Hàm

Python giữ biến giữa các lần gọi hàm

Trong ví dụ sau, chúng tôi muốn chứng minh cách các giá trị toàn cầu có thể được sử dụng bên trong phần thân của hàm

def f(): 
    print(s) 
s = "I love Paris in the summer!"
f()

ĐẦU RA

I love Paris in the summer!

Biến s được định nghĩa là chuỗi "Tôi yêu Paris vào mùa hè. ", trước khi gọi hàm f(). Phần thân của f() chỉ bao gồm câu lệnh "print(s)". Vì không có biến cục bộ s nên tôi. e. không gán cho s, giá trị từ biến toàn cục s sẽ được sử dụng. Vì vậy, đầu ra sẽ là chuỗi "Tôi yêu Paris vào mùa hè. ". Câu hỏi đặt ra là, điều gì sẽ xảy ra nếu chúng ta thay đổi giá trị của s bên trong hàm f()?

def f(): 
    s = "I love London!"
    print(s) 

s = "I love Paris!" 
f()
print(s)

ĐẦU RA

I love London!
I love Paris!

Điều gì sẽ xảy ra nếu chúng ta kết hợp ví dụ đầu tiên với ví dụ thứ hai, tôi. e. trước tiên chúng ta truy cập s bằng hàm print(), hy vọng nhận được giá trị chung, sau đó gán giá trị mới cho nó? . Vì vậy, chúng ta sẽ có s vừa là biến toàn cục vừa là biến cục bộ trong cùng một phạm vi, i. e. phần thân của hàm. Python may mắn thay không cho phép sự mơ hồ này. Vì vậy, nó sẽ phát sinh lỗi, như chúng ta có thể thấy trong ví dụ sau

def f(): 
   print(s)
   s = "I love London!"
   print(s)
 
s = "I love Paris!"
f()

ĐẦU RA

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-3-d7a23bc83c27> in <module>
      5 
      6 s = "I love Paris!"
----> 7 f()
<ipython-input-3-d7a23bc83c27> in f()
      1 def f():
----> 2    print(s)
      3    s = "I love London!"
      4    print(s)
      5 
UnboundLocalError: local variable 's' referenced before assignment

Một biến không thể vừa là cục bộ vừa là toàn cục bên trong một hàm. Vì vậy, Python quyết định rằng chúng ta muốn có một biến cục bộ do việc gán cho s bên trong f(), vì vậy câu lệnh in đầu tiên trước định nghĩa của s đưa ra thông báo lỗi ở trên. Bất kỳ biến nào được thay đổi hoặc tạo bên trong một hàm đều là cục bộ, nếu nó chưa được khai báo là biến toàn cục. Để nói với Python rằng chúng ta muốn sử dụng biến toàn cục, chúng ta phải nói rõ điều này bằng cách sử dụng từ khóa "global", như có thể thấy trong ví dụ sau

def f():
    global s
    print(s)
    s = "Only in spring, but London is great as well!"
    print(s)


s = "I am looking for a course in Paris!" 
f()
print(s)

ĐẦU RA

I am looking for a course in Paris!
Only in spring, but London is great as well!
Only in spring, but London is great as well!

Không thể truy cập biến cục bộ của hàm từ bên ngoài khi lệnh gọi hàm kết thúc. Đây là phần tiếp theo của ví dụ trước

________số 8_______

ĐẦU RA

I am globally not known
Only in spring, but London is great as well!

Ví dụ sau đây cho thấy sự kết hợp hoang dã của các biến cục bộ và biến toàn cầu và các tham số chức năng

I love Paris in the summer!
0

ĐẦU RA

I love Paris in the summer!
1

Đào tạo Python trực tiếp

Python giữ biến giữa các lần gọi hàm

Thưởng thức trang này?

Nhìn thấy. Tổng quan về các khóa học Python trực tiếp

đăng ký tại đây

Biến toàn cục trong hàm lồng nhau

Bây giờ chúng ta sẽ kiểm tra điều gì sẽ xảy ra nếu chúng ta sử dụng từ khóa toàn cục bên trong các hàm lồng nhau. Ví dụ sau đây cho thấy một tình huống trong đó một biến 'thành phố' được sử dụng trong các phạm vi khác nhau

I love Paris in the summer!
2

ĐẦU RA

I love Paris in the summer!
3

Chúng ta có thể thấy rằng câu lệnh toàn cục bên trong hàm lồng nhau g không ảnh hưởng đến biến 'thành phố' của hàm f, i. e. nó giữ nguyên giá trị 'Hamburg'. Chúng ta cũng có thể suy ra từ ví dụ này rằng sau khi gọi f(), một biến 'city' tồn tại trong không gian tên mô-đun và có giá trị 'Geneva'. Điều này có nghĩa là từ khóa toàn cục trong các hàm lồng nhau không ảnh hưởng đến không gian tên của không gian tên kèm theo của chúng. Điều này phù hợp với những gì chúng ta đã tìm hiểu trong chương phụ trước. Một biến được xác định bên trong một hàm là cục bộ trừ khi nó được đánh dấu rõ ràng là toàn cục. Nói cách khác, chúng ta có thể tham chiếu đến tên biến trong bất kỳ phạm vi kèm theo nào, nhưng chúng ta chỉ có thể rebind tên biến trong phạm vi cục bộ bằng cách gán cho nó hoặc trong phạm vi toàn cục mô-đun bằng cách sử dụng khai báo toàn cục. Chúng tôi cũng cần một cách để truy cập các biến của các phạm vi khác. Cách để làm điều này là các định nghĩa không cục bộ, mà chúng tôi sẽ giải thích trong chương tiếp theo

biến không cục bộ

Python3 đã giới thiệu các biến không cục bộ như một loại biến mới. các biến không cục bộ có nhiều điểm chung với các biến toàn cục. Một điểm khác biệt đối với các biến toàn cục nằm ở chỗ không thể thay đổi các biến từ phạm vi mô-đun, i. e. các biến không được xác định bên trong hàm, bằng cách sử dụng câu lệnh không cục bộ. Chúng tôi cho thấy điều này trong hai ví dụ sau

I love Paris in the summer!
4

ĐẦU RA

I love Paris in the summer!
5

Chương trình này đúng và trả về 'Frankfurt' làm đầu ra. Chúng ta sẽ đổi "global" thành "nonlocal" trong chương trình sau

I love Paris in the summer!
6

ĐẦU RA

I love Paris in the summer!
7

Điều này cho thấy rằng các liên kết không cục bộ chỉ có thể được sử dụng bên trong các hàm lồng nhau. Một biến không cục bộ phải được xác định trong phạm vi chức năng kèm theo. Nếu biến không được xác định trong phạm vi chức năng kèm theo, biến không thể được xác định trong phạm vi lồng nhau. Đây là một sự khác biệt khác đối với ngữ nghĩa "toàn cầu"

I love Paris in the summer!
8

ĐẦU RA

I love Paris in the summer!
9

Trong ví dụ trước, biến 'city' được xác định trước lệnh gọi của g. Chúng tôi gặp lỗi nếu nó không được xác định

def f(): 
    s = "I love London!"
    print(s) 

s = "I love Paris!" 
f()
print(s)
0

ĐẦU RA

def f(): 
    s = "I love London!"
    print(s) 

s = "I love Paris!" 
f()
print(s)
1

Chương trình hoạt động tốt - có hoặc không có dòng 'city = "Munich"' bên trong f - , nếu chúng ta thay đổi "nonlocal" thành "global"

Ai là biến giữ lại giá trị của nó giữa các lần gọi hàm?

Biến tĩnh . Một biến giữ lại giá trị của nó giữa nhiều lần gọi hàm được gọi là biến tĩnh.

Các biến cục bộ có thể duy trì dữ liệu của nó giữa các lần gọi hàm không?

Ví dụ: nếu bạn đang sử dụng mô hình Bộ nhớ nhỏ và bạn khai báo một biến cục bộ ở dạng pdata hoặc xdata, biến đó sẽ giữ lại giá trị của nó giữa các lần gọi hàm. However, this may change in future versions of the Compiler and must not be relied upon.

Làm cách nào để sử dụng biến bên ngoài hàm trong hàm Python?

Sử dụng câu lệnh toàn cầu . Chúng tôi làm điều này bằng cách sử dụng tuyên bố toàn cầu. Không thể gán giá trị cho một biến được xác định bên ngoài một hàm mà không có câu lệnh toàn cục.

Bạn có thể gọi một biến từ một hàm khác không?

Không, các biến được khai báo trong hàm là cục bộ của hàm đó . Bạn nên khai báo biến ngoài hàm để sử dụng trong nhiều hàm.