为什么python在函数和类中使用不同的作用域机制?

时间:2013-11-29 14:23:47

标签: python namespaces scope

一些代码和说明:

# 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()

所以,正如我们所见:

  1. 在类中定义函数,内部函数不具有直接在外部类中访问变量的能力。 (我们仍然可以使用类名访问变量。)
  2. 在函数中定义函数,内部函数可以直接在外部函数中访问变量。
  3. 更多代码:

    # 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在函数和类中使用不同的作用域机制?

3 个答案:

答案 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存在于类名称空间中。