That might seem nice for your limited example, but it breaks down when you realize that in example #3 there would be no easy way to differentiate between scopes.
y = 100
x = 15
class MyClass(object):
x = 50
def __init__(self, x):
self.x = x
def length():
return x * y
What does that mean? Does MyClass(10).length() raise an AttributeError because MyClass doesn't have an attribute named y? Does it automatically recognize there's a y in the outer scope and use that, or does it call __getattr__ first (i.e. method that gets called when a missing attribute is accessed)? Furthermore, how do I specify that I want to access the class attribute x, or that I want to access the nonlocal x?