Python-在函数外部创建的对象是否可以在内部完全访问?

我在理解变量范围时遇到一些问题。对于普通变量,我理解这一点,但是如果我定义一个对象,那么事情会使我感到困惑。请看下面的代码:


class test():

    pass


text="hi there"

num=1


p=test()

p.var="good bye"

p.arr = []

p.num = 5


def output_before():

    print "before change: object text " ,p.var

    print "before change: object number ", p.num

    print "before change: basic text " ,text

    print "before change: basic num ", num


def output_after():

    print "after change: object text " ,p.var

    print "after change: object number ", p.num

    print "after change: basic text " ,text

    print "after change: basic num ", num




def change():

    text = "whats up"

    num=5

    p.num=10

    p.var="good night"

    p.arr.append ("sleep well")



output_before()

change()

output_after()


print p.arr


for i in range(5):

    change()

print p.arr

这给了我这个输出:


before change: object text  good bye

before change: object number  5

before change: basic text  hi there

before change: basic num  1

after change: object text  good night

after change: object number  10

after change: basic text  hi there

after change: basic num  1

['sleep well']

['sleep well', 'sleep well', 'sleep well', 'sleep well', 'sleep well', 'sleep well']

默认情况下,来自类测试的对象似乎是全局的。这是正确的吗 ?


海绵宝宝撒
浏览 232回答 3
3回答

慕码人2483693

这就是闭包的工作方式。定义函数时output_after,它将text="hi there"在此函数的变量范围内使用变量。并且只能在函数内部更改此变量。但是,如果要使用全局变量,则需要使用global构造:def output_after():   global text, num   print "after change: object text " ,p.var   print "after change: object number ", p.num   print "after change: basic text " ,text   print "after change: basic num ", num众所周知,Python中的所有变量名称都被称为对值的引用。因此,当我们定义函数时,我们将output_after复制所有当前上下文(对text,num,p对象的引用)。您可以使用id功能检查对对象的引用。当您更改文本和num的值时,引用将被更改,但是对于对象p将会相同。请检查以下内容:def change():    print(id(text))    text = "whats up"    print(id(text))    print(id(num))    num=5    print(id(text))    print(id(p))    p.num=10    print(id(p))您可以看到num和text的引用已更改。

汪汪一只猫

简短答案:在函数外部或全局范围内声明的任何变量(意味着该变量不在任何类型的范围内,例如类,方法,条件语句等)都称为全局变量。长调试的答案:实际上,您的对象被声明为全局对象。p=test()p.var="good bye"p.arr = []p.num = 5在上面的代码片段中,该p对象在方法范围之外进行了声明,从而允许所有对象都可以访问它。方法也在test类范围之外声明。实际上,没有什么阻止他们访问它。如果要更好地理解调试,请将p对象移至其中一种方法中,例如:def output_before():   p=test()   p.var="good bye"   p.arr = []   p.num = 5   print "before change: object text " ,p.var   print "before change: object number ", p.num   print "before change: basic text " ,text   print "before change: basic num ", num并重新运行您的代码,将产生:before change: object text  good byebefore change: object number  5before change: basic text  hi therebefore change: basic num  1然后出现以下错误:追溯(最近一次呼叫最近):change()中的文件“ t.py”,第35行,更改中的文件“ t.py”,第29行,p.num = 10 NameError:未定义全局名称“ p”但是,如果要从模块或方法内部访问对象,则可以使用关键字global,并且如文档所建议的那样:这是因为当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并在外部作用域中隐藏任何类似命名的变量。由于foo中的最后一条语句为x分配了一个新值,因此编译器将其识别为局部变量。因此,当较早的打印x尝试打印未初始化的局部变量并导致错误时,可以通过将其声明为全局变量来访问外部作用域变量

人到中年有点甜

就像Python中的其他任何变量一样。该函数首先在本地名称空间中检查变量。由于未在函数内部定义对象,因此它将检查外部命名空间,即您实际定义其的全局命名空间。对于变量num /文本,您使用num = 5在change()。这将创建一个名为的局部变量,num并为其分配5。它不会更改全局变量。如果要全局更改它,则可以使用global关键字:def change():    global text,num    num = 5  #Global num is changed
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python