0Pricing
Python Academy · บทเรียน

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชันชั้นหนึ่ง
  2. คลอเชอร์และตัวแปรอิสระ
  3. nonlocal และสถานะที่เปลี่ยนแปลงได้
  4. ฟังก์ชันบางส่วน
← กลับไปที่ Python Academy