DEV Community

Cover image for Variable Shadowing in Python and Go
Sajjad Rahman
Sajjad Rahman

Posted on

Variable Shadowing in Python and Go

1. What is Variable Shadowing?

Variable shadowing occurs when a local variable in a scope has the same name as a variable in an outer scope. The inner variable โ€œshadowsโ€ the outer one, so references inside the inner scope use the inner variable, not the outer one.

2. Python Example

Global vs Local Shadowing

x = 10  # Global variable

def my_func():
    x = 5  # Shadows the global 'x'
    print("Inside function:", x)

my_func()
print("Outside function:", x)
Enter fullscreen mode Exit fullscreen mode

Output:

Inside function: 5
Outside function: 10
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The function has its own x, which shadows the global x.
  • The global variable remains unchanged.

Class / Instance Shadowing

name = "GlobalName"

class Person:
    name = "ClassName"  # Shadows the global 'name'

    def __init__(self):
        self.name = "InstanceName"  # Shadows class variable

p = Person()
print(name)        # GlobalName
print(Person.name) # ClassName
print(p.name)      # InstanceName
Enter fullscreen mode Exit fullscreen mode

Key takeaway:

  • Shadowing can happen at global โ†’ class โ†’ instance levels in Python.

Modifying Global Variables

x = 10

def f():
    global x
    x = x + 1  # Works because we use 'global'

f()
print(x)  # 11
Enter fullscreen mode Exit fullscreen mode

Without global, Python will throw UnboundLocalError.

3. Go (Golang) Example

Package-level vs Local Shadowing

package main

import "fmt"

var x = 10 // package-level variable

func main() {
    x := 5 // Shadows package-level 'x'
    fmt.Println("Inside main:", x)
    printGlobal()
}

func printGlobal() {
    fmt.Println("Global x:", x)
}
Enter fullscreen mode Exit fullscreen mode

Output:

Inside main: 5
Global x: 10
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • x := 5 in main shadows the package-level x.
  • Shadowing only affects the current scope (main).

Nested Shadowing

package main

import "fmt"

var val = 100

func outer() {
    val := 50 // Shadows global 'val'
    fmt.Println("Outer val:", val)
    inner()
}

func inner() {
    val := 25 // Shadows outer function's val? โŒ Not accessible
    fmt.Println("Inner val:", val)
}

func main() {
    outer()
    fmt.Println("Global val:", val)
}
Enter fullscreen mode Exit fullscreen mode

Output:

Outer val: 50
Inner val: 25
Global val: 100
Enter fullscreen mode Exit fullscreen mode

Key points in Go:

  • Go allows shadowing in nested scopes.
  • Shadowing is resolved at compile-time.
  • Using := creates a new local variable, shadowing outer variables.

4. Summary Table

Feature Python Go
Shadowing allowed โœ… Yes โœ… Yes
Global modification global keyword needed Use package-level variable
Function scope Shadows outer variables Shadows package-level vars
Class/Instance scope โœ… Yes (class & instance level) โŒ No class concept
Nested shadowing โœ… Yes โœ… Yes
Errors on unintentional access UnboundLocalError Compile-time shadowing

Thank you for your readi and follow me for updates and more tutorials

Top comments (0)