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

为什么python在函数和类中使用不同的作用域机制?,python,namespaces,scope,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 O

一些代码和说明:

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

    因为两者的生存期和可见性完全不同

    可以访问类的任何对象都可以访问类属性。类属性还必须处理继承问题;如果我这样写代码会怎么样:

    class Foo(object):
        def eggs(self):
            print eggs()
    
    class Bar(Foo):
        def ham(self):
            print eggs()
    
    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
    
    按照您的逻辑,为什么
    鸡蛋
    应该在
    Foo.eggs
    中可见,而不是在
    Bar.ham

    函数局部变量只能由函数和函数中嵌套的任何对象访问。再次调用该函数,就会得到一组新的变量

    因此,当您创建一个类实例并对该实例调用一个方法时,其他代码可能会同时更改类属性。函数闭包(在嵌套作用域中访问的局部变量)不能从函数外部更改


    不能将这两个作用域视为完全相同。

    没有不同的机制


    var1
    在方法
    f1
    中不可用,因为方法的代码在调用该方法的命名空间中执行<另一方面,code>var1存在于类名称空间中。

    您描述的是两个几乎不相关的东西,它们碰巧具有相似的缩进

    class Class1(object):
        var1 = 11
    
    这是在
    Class1
    上定义一个新属性,您可以通过
    Class1.var1
    或类的一个方法(如
    self.var1
    )访问
    var1
    属性,例如:

    class Class1(object):
        var1 = 11
        def f1(self):
            print self.var1
    
    这可能更常见于以下情况:

    class Foo(object):
        def eggs(self):
            print eggs()
    
    class Bar(Foo):
        def ham(self):
            print eggs()
    
    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
    
    …您将使用如下方式:

    class Foo(object):
        def eggs(self):
            print eggs()
    
    class Bar(Foo):
        def ham(self):
            print eggs()
    
    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
    
    或通常用于定义类上的静态属性,如下所示:

    class Foo(object):
        def eggs(self):
            print eggs()
    
    class Bar(Foo):
        def ham(self):
            print eggs()
    
    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
    
    请记住,这些属性是在类定义时定义的,因此这些属性在类的所有实例(某物)之间共享

    您描述的第二件事是词法范围,其中变量在封闭函数中可用,通常使用如下方式:

    class Foo(object):
        def eggs(self):
            print eggs()
    
    class Bar(Foo):
        def ham(self):
            print eggs()
    
    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
    

    这些是作用域,而不是名称空间。您的代码很奇怪,而不是
    print Class1.var1#这样就可以了
    我们更希望看到
    print self.var1
    。你对python完全陌生,不是吗?非常感谢你的帮助!从“因此,当您创建一个类实例并在该实例上调用一个方法时,类属性可能会同时被其他代码更改”中学到很多东西。真正的区别在于名称空间和范围。非常感谢!从你的代码中获得很多。还有一点抱歉,这个网站只允许我接受一个答案。