Truy cập biến cục bộ bên ngoài phạm vi trong python

Loại “tuổi thọ thay đổi” này được gọi là xác định phạm vi. Sau khi đọc bài viết này, bạn sẽ biết các quy tắc phạm vi của Python. Hãy bắt đầu

3 phạm vi của Python

Python có 3 phạm vi

  • Toàn cầu. Trong phần chính của kịch bản. Theo mặc định, điều này đã chứa sẵn. Bạn có thể truy cập tất cả các biến toàn cầu với
    Traceback (most recent call last):
    File "example.py", line 5, in
    foo()
    File "example.py", line 2, in foo
    print(min([1, 2, 3]))
    UnboundLocalError: local variable 'min' referenced before assignment
    7
  • Gửi kèm. Trong chức năng bên ngoài, nếu đây là một chức năng lồng nhau
  • Địa phương. Trong chức năng hiện tại. Bạn có thể truy cập tất cả các biến cục bộ với
    Traceback (most recent call last):
    File "example.py", line 5, in
    foo()
    File "example.py", line 2, in foo
    print(min([1, 2, 3]))
    UnboundLocalError: local variable 'min' referenced before assignment
    8. Trong kịch bản chính,
    Traceback (most recent call last):
    File "example.py", line 5, in
    foo()
    File "example.py", line 2, in foo
    print(min([1, 2, 3]))
    UnboundLocalError: local variable 'min' referenced before assignment
    9

Bạn có thể thấy cả ba hoạt động ở đây

Có một điểm quan trọng ở đây

Phạm vi của một biến được xác định tại thời điểm biên dịch

Vì lý do này, đoạn mã sau đưa ra một ngoại lệ

def foo():
print(min([1, 2, 3]))
min = lambda n: "local"
foo()

ném ngoại lệ

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment

Tuyên bố “toàn cầu”

Bạn có thể gán giá trị cho biến toàn cục trong hàm bằng câu lệnh toàn cục

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"

Tôi rất hiếm khi cần cái này. Để đảm bảo rằng tôi không nhầm lẫn bất cứ điều gì, tôi thích sử dụng từ điển

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
7. Trong trường hợp này, tôi thà sử dụng

x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"

Tuyên bố "phi cục bộ"

Bạn có thể gán một giá trị cho một biến kèm theo với câu lệnh không cục bộ

________số 8

Ví dụ khó hiểu

Hình ảnh của wokandapix (nguồn)

Nối phần tử so với '+= [phần tử]'

xs = []def foo():
xs.append(42) # OK
foo()

so với

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
0

Lý do tại sao cái đầu tiên hoạt động nhưng cái thứ hai không hoạt động là cái đầu tiên gọi một hàm của xs. Nó không bao giờ gán giá trị cho xs. Cái thứ hai bằng

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
1

Khi Python phân tích cú pháp gán

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
1 ,
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
2 được gán phạm vi cục bộ. Nhưng trong phạm vi cục bộ,
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
2 không tồn tại trước khi
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
4 được thực thi. Do đó lỗi

Trong ví dụ đầu tiên với

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
5 , phạm vi toàn cầu của
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
2 được sử dụng. Do đó, chúng tôi không gặp phải bất kỳ vấn đề nào, vì nó được xác định trong phạm vi toàn cầu

Phạm vi toàn cầu KHÔNG quay trở lại tích hợp sẵn

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
8

nhưng điều tương tự không hoạt động trong phạm vi cục bộ

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
9

Lý do là

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
9 trong phạm vi toàn cầu. Mặc dù các phần mềm tích hợp hơi đặc biệt, nhưng chúng tồn tại trong phạm vi toàn cầu

Phân công

Điều này gây nhầm lẫn cho những người có nền tảng Java, C hoặc C ++. Đây là mã Python hợp lệ

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
0

Nhưng trong Java bạn cần khai báo nó trước để có thể sử dụng biến sau vòng lặp

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
1

mypy

mypy là một trình kiểm tra kiểu phổ biến cho Python

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
2

Vì vậy, mypy không thích việc bạn gán chuỗi “foo” cho

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
8, bởi vì lần đầu tiên đọc nó lấy đường dẫn
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
9 và giả định rằng
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
8 sẽ là một số nguyên

Sau đó, bạn có thể muốn làm điều này

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
3

Bạn có thể thấy rằng mypy cho rằng

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
8 phải cùng loại trong cả hai trường hợp. Điều đó hợp lý vì nếu không thì phân tích sau đây có thể trở nên cực kỳ phức tạp

Lần thử tiếp theo có thể là

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
4

Điều đó nên đã được mong đợi. Không thể gán

x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
2 cho một loại không bao gồm
x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
2 — và việc thêm
x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
2 vào loại đó có thể gây ra nhiều vấn đề khác sau này

Bạn có thể làm được việc này

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
5

Nhưng tôi cũng có thể thấy khi điều này cảm thấy lạ. Cái này có thể sạch hơn

Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
6

Bản tóm tắt

Chúng ta đã thấy ba loại phạm vi trong Python. Cục bộ, kèm theo và toàn cầu. Chúng tôi đã thấy rằng bạn có thể truy cập toàn cầu bằng từ khóa

x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
5 hoặc qua từ điển
Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
7. Các địa phương có thể được truy cập bằng từ điển
Traceback (most recent call last):
File "example.py", line 5, in
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
8 và các biến kèm theo với từ khóa
x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
8. Hãy ghi nhớ điều đó và phạm vi Python sẽ có ý nghĩa 🙂

Biến cục bộ có thể được sử dụng bên ngoài phạm vi của nó không?

Biến cục bộ . Bất cứ điều gì giữa '{' và '}' được cho là bên trong một khối. Các biến cục bộ không tồn tại bên ngoài khối mà chúng được khai báo, i. e. không thể truy cập hoặc sử dụng chúng bên ngoài khối đó .

Biến cục bộ có thể được sử dụng ở bất kỳ đâu trong Python không?

Biến cục bộ trong Python . A variable that is declared inside a python function or a module can only be used in that specific function or Python Module.