2009-05-30 56 views
49

Tôi đang gặp sự cố khủng khiếp khi cố hiểu các quy tắc phạm vi python.Tại sao việc gán cho các biến toàn cầu của tôi không hoạt động trong Python?

Với kịch bản sau đây:

a = 7 

def printA(): 
    print "Value of a is %d" % (a) 

def setA(value): 
    a = value 
    print "Inside setA, a is now %d" %(a) 


print "Before setA" 
printA() 
setA(42) 
print "After setA" 
printA() 

Cung cấp cho những điều bất ngờ (với tôi) sản lượng:

 
    Before setA 
    Value of a is 7 
    Inside setA, a is now 42 
    After setA 
    Value of a is 7 

Nơi tôi mong chờ việc in ấn cuối cùng của giá trị của một là 42, không 7. Tôi thiếu gì về các quy tắc phạm vi của Python đối với phạm vi biến toàn cầu?

Trả lời

97

Biến toàn cục là đặc biệt. Nếu bạn cố gắng gán cho một biến số a = value bên trong một hàm, nó tạo ra một biến cục bộ mới bên trong hàm, ngay cả khi có một biến toàn cục có cùng tên. Để thay vì truy cập vào biến toàn cầu, thêm một global statement bên trong hàm:

a = 7 
def setA(value): 
    global a # declare a to be a global 
    a = value # this sets the global value of a 

Xem thêm Naming and binding cho một lời giải thích chi tiết về cách đặt tên Python và quy tắc ràng buộc.

+12

* (thô lỗ từ) * python – theonlygusti

11

Bí quyết để hiểu điều này là khi bạn gán cho một biến, sử dụng =, bạn cũng khai báo nó dưới dạng biến cục bộ. Vì vậy, thay vì thay đổi giá trị của biến toàn cục a, setA (giá trị) thực sự đặt biến cục bộ (được gọi là a) thành giá trị được chuyển.

Điều này trở nên rõ ràng hơn nếu bạn cố gắng in giá trị một khi bắt đầu Seta (giá trị) như sau:

def setA(value): 
    print "Before assignment, a is %d" % (a) 
    a = value 
    print "Inside setA, a is now %d" % (a) 

Nếu bạn cố gắng chạy Python này sẽ cung cấp cho bạn một lỗi hữu ích:

 
Traceback (most recent call last): 
    File "scopeTest.py", line 14, in 
    setA(42) 
    File "scopeTest.py", line 7, in setA 
    print "Before assignment, a is %d" % (a) 
UnboundLocalError: local variable 'a' referenced before assignment 

này cho chúng ta biết Python đã quyết định rằng Hàm setA (value) có một biến cục bộ được gọi là a, đó là những gì bạn thay đổi khi bạn ass bỏ qua nó trong hàm. Nếu bạn không gán cho một hàm trong hàm (như với printA()) thì Python sẽ sử dụng biến toàn cầu A.

Để đánh dấu một biến là toàn cầu bạn cần sử dụng từ khóa chung trong Python, trong phạm vi bạn muốn sử dụng biến toàn cục. Trong trường hợp này nằm trong hàm setA (value). Vì vậy, tập lệnh trở thành:

a = 7 

def printA(): 
    print "Value of a is %d" % (a) 

def setA(value): 
    global a 
    a = value 
    print "Inside setA, a is now %d" %(a) 


print "Before setA" 
printA() 
setA(42) 
print "After setA" 
printA() 

Bổ sung một dòng này cho Python biết khi bạn sử dụng biến a trong hàm setA (giá trị) mà bạn đang nói về biến toàn cục, không phải biến cục bộ.

2

Python không có khái niệm về các biến như các ngôn ngữ khác. Bạn có các đối tượng "ở đâu đó" và bạn có tham chiếu đến các đối tượng này. = được sử dụng để gán các đối tượng này tham chiếu trong không gian tên hiện tại.

Bạn tạo một tên trong không gian tên của hàm setA tham chiếu đến đối tượng mà giá trị đó đề cập đến.

1

bên trong hàm, một được coi là một biến địa phương, bạn cần phải xác định

global a

bên trong hàm

Các vấn đề liên quan