nonlocal และสถานะที่เปลี่ยนแปลงได้
แก้ไขขอบเขตที่ครอบอยู่
nonlocal และสถานะที่เปลี่ยนแปลงได้ เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
การอ่านและการเขียนตัวแปรในขอบเขตที่ครอบอยู่
ฟังก์ชันด้านในสามารถอ่านตัวแปรจากขอบเขตที่ครอบอยู่ได้อย่างอิสระ แต่หากพยายามกำหนดค่าให้ชื่อนั้น Python จะถือว่าเป็นตัวแปรภายในใหม่แทน เรื่องนี้มักทำให้ผู้เริ่มต้นสับสน
def outer():
count = 0
def inner():
return count
return inner()
print(outer())กับดักการกำหนดค่า
การกำหนดค่าให้ชื่อจากขอบเขตที่ครอบอยู่โดยไม่ประกาศเจตนาจะทำให้ชื่อนั้นเป็นตัวแปรภายใน ดังนั้นตัวแปรด้านนอกจึงไม่ถูกปรับปรุง และการเปลี่ยนแปลงในที่นี้จะสูญหายไป
def outer():
count = 0
def bump():
count = count + 1
try:
bump()
except UnboundLocalError as e:
print('Error:', e)
outer()คำสำคัญสำหรับตัวแปรในฟังก์ชันที่ครอบอยู่
nonlocal ประกาศว่าชื่อหนึ่งอ้างถึงตัวแปรในขอบเขตของฟังก์ชันที่ครอบอยู่ใกล้ที่สุด ดังนั้นการกำหนดค่าจะปรับปรุงตัวแปรด้านนอกแทนการสร้างตัวแปรภายในใหม่
def outer():
count = 0
def bump():
nonlocal count
count += 1
bump()
bump()
return count
print(outer())คลอเชอร์ตัวนับ
การใช้ nonlocal ช่วยให้คุณสร้างตัวนับที่มีสถานะได้ การเรียกใช้แต่ละครั้งจะเปลี่ยนค่าตัวแปรที่จับไว้และจดจำความคืบหน้าไว้
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
c = make_counter()
print(c())
print(c())
print(c())ตัวนับที่เป็นอิสระต่อกัน
ตัวนับแต่ละตัวเก็บสถานะของตนเองไว้ เพราะคลอเชอร์แต่ละรายการจับตัวแปรแยกกัน
def make_counter():
count = 0
def inc():
nonlocal count
count += 1
return count
return inc
a = make_counter()
b = make_counter()
print(a(), a(), b())ขอบเขตฟังก์ชันที่ครอบอยู่กับขอบเขตส่วนกลาง
nonlocal อ้างถึงขอบเขตของฟังก์ชันที่ครอบอยู่ ส่วน global อ้างถึงระดับโมดูล ควรใช้ nonlocal กับคลอเชอร์ และใช้ global กับสถานะที่ใช้ทั่วทั้งโมดูล
total = 0
def add_global(n):
global total
total += n
add_global(5)
add_global(3)
print(total)สถานะที่เปลี่ยนแปลงได้โดยไม่ใช้ nonlocal
หากค่าที่อยู่ในขอบเขตที่ครอบอยู่เป็นอ็อบเจกต์ที่เปลี่ยนแปลงได้ เช่น รายการหรือพจนานุกรม คุณสามารถเปลี่ยนแปลงอ็อบเจกต์นั้นโดยตรงได้โดยไม่ต้องใช้ nonlocal เพราะคุณไม่ได้กำหนดชื่อใหม่ให้ชี้ไปยังอ็อบเจกต์อื่น
def make_logger():
history = []
def log(msg):
history.append(msg)
return history
return log
log = make_logger()
log('start')
print(log('stop'))ตัวสะสม
การผสาน nonlocal เข้ากับคลอเชอร์ช่วยให้สร้างตัวสะสมที่เพิ่มค่าแต่ละค่าเข้ากับผลรวมที่จดจำไว้ได้
def make_accumulator():
total = 0
def add(n):
nonlocal total
total += n
return total
return add
acc = make_accumulator()
print(acc(10))
print(acc(5))
print(acc(100))toggle อย่างง่าย
การอ้างถึงตัวแปรในฟังก์ชันที่ครอบอยู่ช่วยให้สลับสถานะบูลีนไปมาระหว่างการเรียกใช้แต่ละครั้งได้ง่าย
def make_toggle():
on = False
def toggle():
nonlocal on
on = not on
return on
return toggle
t = make_toggle()
print(t(), t(), t())การรีเซ็ตสถานะ
คุณสามารถเปิดเผยฟังก์ชันด้านในหลายรายการที่ใช้สถานะจากขอบเขตเดียวกันร่วมกันได้ เช่น ฟังก์ชันหนึ่งสำหรับ add และอีกฟังก์ชันหนึ่งสำหรับ reset
def make_bank():
balance = 0
def deposit(n):
nonlocal balance
balance += n
return balance
def reset():
nonlocal balance
balance = 0
return balance
return deposit, reset
deposit, reset = make_bank()
print(deposit(50))
print(reset())การอ้างถึงตัวแปรในฟังก์ชันที่ครอบอยู่ต้องมีตัวแปรอยู่ก่อน
nonlocal ต้องการให้ชื่อนั้นมีอยู่แล้วในขอบเขตที่ครอบอยู่ มิฉะนั้น Python จะทำให้เกิด SyntaxError ขณะประกาศฟังก์ชัน และไม่สามารถสร้างตัวแปรด้านนอกใหม่ได้
def outer():
value = 'set'
def inner():
nonlocal value
value = 'changed'
inner()
return value
print(outer())ตรวจสอบความเข้าใจ
ภายในฟังก์ชันซ้อนกัน คุณต้องการกำหนดค่าใหม่ให้ตัวแปรจากฟังก์ชันที่ครอบอยู่ คุณควรใช้คำสำคัญใด
สรุปทบทวน: nonlocal และสถานะที่เปลี่ยนแปลงได้
สรุป:
- โดยปกติการกำหนดค่าให้ชื่อจากขอบเขตที่ครอบอยู่จะสร้างตัวแปรภายในใหม่ แต่
nonlocalจะป้องกันไม่ให้เกิดเช่นนั้น nonlocalอ้างถึงขอบเขตของฟังก์ชันที่ครอบอยู่ ส่วนglobalอ้างถึงโมดูล- การเปลี่ยนแปลงอ็อบเจกต์ที่เปลี่ยนแปลงได้โดยตรงไม่จำเป็นต้องมีการประกาศ
- คลอเชอร์ที่ใช้
nonlocalสามารถสร้างตัวนับ ตัวสะสม และ toggle ที่จดจำสถานะได้
def make_counter():
n = 0
def inc():
nonlocal n
n += 1
return n
return inc
c = make_counter()
print(c(), c())คำถามที่พบบ่อย
บทเรียน “nonlocal และสถานะที่เปลี่ยนแปลงได้” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “nonlocal และสถานะที่เปลี่ยนแปลงได้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “nonlocal และสถานะที่เปลี่ยนแปลงได้”
แก้ไขขอบเขตที่ครอบอยู่ คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “nonlocal และสถานะที่เปลี่ยนแปลงได้” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม
ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ฟังก์ชันชั้นหนึ่ง
- คลอเชอร์และตัวแปรอิสระ
- nonlocal และสถานะที่เปลี่ยนแปลงได้
- ฟังก์ชันบางส่วน