0

Some code and descriptions:

# name_space.py class Class1(object): var1 = 11 def f1(self): print Class1.var1 # this will OK print var1 # this will be an error def func_1(): var1 = 11 def func_2(): print var1 # here will be OK func_2() 

So, as we can see:

  1. Define a function in a class, the inner function doesn't have the ability to access the variables directly in the outer class. (We can still access the variables with the class name).
  2. Define a function in a function, the inner function has the ability to access the variables directly in the outer function.

More codes:

# name_space2.py class A(object): def f1(self): def f2(): print f1 # this will be an error print A.f1 # this will OK f2() 

So, why python use different scope mechanisms in function and class?

2
  • 3
    Those are scopes, not namespaces. Commented Nov 29, 2013 at 14:25
  • 2
    you're code is strange, instead of print Class1.var1 # this will OK we'd rather see print self.var1. You're entirely new to python aren't you ? Commented Nov 29, 2013 at 14:26

3 Answers 3

1

Because the lifetime and visibility of both is entirely different.

Class attributes are accessible by anything that can access the class. Class attributes also have to play with inheritance; what if I wrote code like this:

class Foo(object): def eggs(self): print eggs() class Bar(Foo): def ham(self): print eggs() 

By your logic, why should eggs be visible in Foo.eggs but not in Bar.ham?

Function locals are only accessible to the function and anything nested within the function. Call the function again and you get a fresh set of variables.

So when you create a class instance and call a method on that instance, the class attributes could have been changed by other code in the meantime. Function closures (locals accessed in a nested scope) cannot be changed from outside the function.

You cannot treat the two scopes as the same at all.

Sign up to request clarification or add additional context in comments.

1 Comment

Great help, thanks very much! Learn a lot from "So when you create a class instance and call a method on that instance, the class attributes could have been changed by other code in the meantime."
1

You are describing two mostly unrelated things, which happen to have similar indentation..

class Class1(object): var1 = 11 

This is defining a new attribute on the Class1, you would access the var1 attribute either via Class1.var1, or inside one of the class's methods like self.var1, e.g:

class Class1(object): var1 = 11 def f1(self): print self.var1 

It's maybe more commonly seen in things like this:

class Class1(object): def mygetter(self): return 42 def mysetter(self, val): print "mysetter got value of", val myprop = property(mygetter, mysetter) 

..which you would use like this:

c = Class1() print c.myprop # 42 c.myprop = 100 # prints "mysetter got value of 100" 

Or often used for defining static attributes on classes, like this:

class Class1(object): THING = 1 ANOTHER = "blah" ... 

Remember these are defined at class definition time, so the attributes are shared between all instances of the class (something I found initially confusing)

The second thing you describe is lexical scoping, where variables are available in enclosed functions, often used like this:

def outer(): myvar = 42 def inner(): print myvar * 2 return inner 

1 Comment

The real difference is namespace and scope. Thanks very much! Gain a lot from you codes. And a little sorry, this site allows me to accept only one answer.
0

There is no different mechanism.

var1 is not available inside method f1 because method's code is executed in the namespace where the method is called. var1 on the other hand exists in the class namespace.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.