一些代码和说明:
# 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()
所以,正如我们所见:
更多代码:
# 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()
那么,为什么python在函数和类中使用不同的作用域机制?
答案 0 :(得分:1)
因为两者的生命周期和可见性完全不同。
可以访问类的任何东西都可以访问类属性。类属性也必须使用继承;如果我写这样的代码怎么办:
class Foo(object):
def eggs(self):
print eggs()
class Bar(Foo):
def ham(self):
print eggs()
根据您的逻辑,为什么eggs
可以Foo.eggs
显示Bar.ham
而不是{{1}}?
函数本地只能被函数访问,并且任何嵌套在函数中的东西都可以访问。再次调用该函数,您将获得一组新的变量。
因此,当您在该实例上创建一个类实例并调用一个方法时,其他代码可能同时更改了该类属性。函数闭包(在嵌套作用域中访问的本地)不能从函数外部更改。
您根本无法将两个范围视为相同。
答案 1 :(得分:1)
你正在描述两个大多数不相关的东西,碰巧有类似的缩进。
class Class1(object):
var1 = 11
这是在Class1
上定义新属性,您可以通过var1
访问Class1.var1
属性,也可以在self.var1
类的方法中访问class Class1(object):
var1 = 11
def f1(self):
print self.var1
属性,例如:
class Class1(object):
def mygetter(self):
return 42
def mysetter(self, val):
print "mysetter got value of", val
myprop = property(mygetter, mysetter)
在这样的事情中可能更常见:
c = Class1()
print c.myprop # 42
c.myprop = 100 # prints "mysetter got value of 100"
..您可以这样使用:
class Class1(object):
THING = 1
ANOTHER = "blah"
...
或经常用于在类上定义静态属性,如下所示:
def outer():
myvar = 42
def inner():
print myvar * 2
return inner
请记住这些是在类定义时间中定义的,因此属性在类的所有实例之间共享(I found initially confusing}
你描述的第二件事是词法范围,其中变量在封闭函数中可用,通常像这样使用:
{{1}}
答案 2 :(得分:0)
没有不同的机制。
var1
在方法f1
中不可用,因为方法的代码在调用方法的命名空间中执行。另一方面,var1
存在于类名称空间中。