Skip to main content

Keyword nonlocal

Keyword nonlocal digunakan pada nested function untuk mengakses dan mengubah variabel yang berada pada Enclosing Scope, yaitu scope function yang membungkus function tersebut.

Dengan kata lain, nonlocal memungkinkan sebuah function di dalam function untuk mengubah variabel milik function induknya.

Konsep ini berkaitan erat dengan aturan pencarian scope LEGB:

L → Local
E → Enclosing
G → Global
B → Built-in

Enclosing Scope​

Sebelum memahami nonlocal, kita perlu memahami Enclosing Scope.

Enclosing Scope adalah scope milik function yang membungkus nested function.

Contoh:

def outer():
x = "local"

def inner():
print(x)

inner()

outer()

Output:

local

Function inner() tidak memiliki variabel x sendiri.

Python kemudian mencari ke scope yang membungkusnya, yaitu outer().

Di sana Python menemukan:

x = "local"

Sehingga nilai tersebut dapat digunakan oleh inner().


Masalah ketika Mengubah Variabel Enclosing​

Sekarang perhatikan contoh berikut:

def outer():
x = "local"

def inner():
x = "nonlocal"
print(x)

inner()
print(x)

outer()

Output:

nonlocal
local

Mengapa nilai x pada outer() tetap "local"?

Karena:

x = "nonlocal"

di dalam inner() membuat variabel lokal baru untuk inner().

Variabel tersebut berbeda dengan:

x = "local"

yang berada di outer().

Secara sederhana:

outer()
└── x = "local"
│
└── inner()
└── x = "nonlocal"

Terdapat dua variabel x yang berbeda.


Menggunakan nonlocal​

Jika kita ingin mengubah variabel x milik outer(), gunakan keyword nonlocal.

def outer():
x = "local"

def inner():
nonlocal x
x = "nonlocal"
print("inner:", x)

inner()
print("outer:", x)

outer()

Output:

inner: nonlocal
outer: nonlocal

Baris:

nonlocal x

memberitahu Python:

Gunakan variabel x yang berada pada Enclosing Scope, bukan membuat variabel lokal baru.


Perbedaan Tanpa nonlocal​

Tanpa nonlocal:

def outer():
x = "local"

def inner():
x = "nonlocal"

inner()
print(x)

outer()

Output:

local

Assignment:

x = "nonlocal"

membuat variabel lokal baru di dalam inner().


Perbedaan dengan nonlocal​

Dengan nonlocal:

def outer():
x = "local"

def inner():
nonlocal x
x = "nonlocal"

inner()
print(x)

outer()

Output:

nonlocal

Sekarang inner() tidak membuat variabel x baru.

inner() menggunakan dan mengubah x yang dimiliki oleh outer().


Cara Kerja nonlocal​

Perhatikan struktur berikut:

Global Scope
│
└── outer()
│
├── x = "local"
│
└── inner()
│
└── nonlocal x

Ketika Python menemukan:

nonlocal x

Python akan mencari x pada Enclosing Scope.

Python tidak mencari x pada Global Scope.

Inilah perbedaan penting antara nonlocal dan global.


nonlocal vs global​

global​

Digunakan untuk mengakses atau mengubah variabel pada Global Scope.

x = 10

def example():
global x
x = 20

example()

print(x)

Output:

20

nonlocal​

Digunakan untuk mengakses atau mengubah variabel pada Enclosing Scope.

def outer():
x = 10

def inner():
nonlocal x
x = 20

inner()
print(x)

outer()

Output:

20

Perbedaannya:

global
→ mengarah ke Global Scope

nonlocal
→ mengarah ke Enclosing Scope

nonlocal Hanya untuk Nested Function​

Keyword nonlocal digunakan ketika terdapat enclosing function.

Contoh yang benar:

def outer():
x = 10

def inner():
nonlocal x
x = 20

inner()

outer()

Sedangkan penggunaan nonlocal tanpa enclosing scope yang sesuai akan menghasilkan error.

Contoh:

def example():
nonlocal x

Kode tersebut tidak valid karena tidak terdapat function pembungkus yang memiliki variabel x.


Contoh Counter dengan nonlocal​

Salah satu contoh penggunaan nonlocal adalah membuat counter menggunakan nested function.

def counter():
count = 0

def increment():
nonlocal count
count += 1
return count

return increment

Kita dapat membuat counter:

my_counter = counter()

print(my_counter())
print(my_counter())
print(my_counter())

Output:

1
2
3

Variabel:

count = 0

berada di counter().

Function increment() menggunakan:

nonlocal count

untuk mengubah variabel tersebut.


Mengapa Counter Tetap Menyimpan Nilai?​

Ketika:

my_counter = counter()

function counter() membuat variabel:

count = 0

dan mengembalikan function increment.

Function increment() tetap dapat mengakses count milik counter().

Kemudian setiap kali:

my_counter()

dipanggil:

count += 1

akan mengubah nilai count.

Konsep ini berkaitan dengan closure, yang akan menjadi penting ketika mempelajari konsep function tingkat lanjut.


LEGB dan nonlocal​

nonlocal berhubungan langsung dengan bagian E — Enclosing pada LEGB.

Aturan LEGB:

L → Local
E → Enclosing
G → Global
B → Built-in

Contoh:

def outer():
x = 10

def inner():
print(x)

inner()

outer()

Saat mencari x di inner():

Local
↓
tidak ditemukan

Enclosing
↓
x = 10 ditemukan

Jika kita ingin mengubah nilai x tersebut, gunakan:

nonlocal x

Kapan Menggunakan nonlocal?​

nonlocal berguna terutama ketika:

  • Menggunakan nested function.
  • Function bagian dalam perlu mengubah state function induknya.
  • Membuat closure.
  • Membuat pola seperti counter atau state sederhana yang tetap tersimpan.

Contoh:

def counter():
count = 0

def increment():
nonlocal count
count += 1
return count

return increment

Hindari Penggunaan Berlebihan​

Walaupun nonlocal berguna, penggunaannya secara berlebihan dapat membuat alur program menjadi lebih sulit dipahami.

Contoh:

def outer():
total = 0

def add():
nonlocal total
total += 10

def subtract():
nonlocal total
total -= 5

add()
subtract()

return total

Beberapa nested function dapat mengubah state yang sama.

Pada program yang lebih besar, kondisi seperti ini dapat membuat kita kesulitan mengetahui function mana yang mengubah suatu nilai.

Karena itu, gunakan nonlocal ketika memang sesuai dengan struktur program.


Ringkasan​

KeywordScope yang DiaksesPenggunaan
globalGlobal ScopeMengubah variabel global
nonlocalEnclosing ScopeMengubah variabel function induk
Tidak menggunakan keduanyaLocal ScopeAssignment membuat variabel lokal

Contoh global:

total = 0

def update():
global total
total += 1

Contoh nonlocal:

def outer():
total = 0

def update():
nonlocal total
total += 1

Kesimpulan​

Keyword nonlocal digunakan pada nested function untuk mengakses dan mengubah variabel yang berada pada Enclosing Scope.

Tanpa nonlocal:

x = "nonlocal"

akan membuat variabel lokal baru.

Dengan nonlocal:

nonlocal x
x = "nonlocal"

Python akan mengubah variabel x milik function induknya.

Konsep ini merupakan bagian penting dari pemahaman LEGB, nested function, dan nantinya closure.