首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域

在 python 中赋值语句总是建立对象的引用值,而不是复制对象。...执行完毕后,values 标签还是指向原来那个对象,只不过那个对象的结构发生了变化,从之前的列表 [0, 1, 2] 变成了 [0, ?, 2],而这个 ? 则是指向那个对象本身的一个引用。...在函数参数传递的时候,Python其实就是把参数里传入的变量对应的对象的引用依次赋值给对应的函数内部变量。...= 'bar'这句中,它是“有歧义的“,因为它既可以是表示引用全局变量s,也可以是创建一个新的局部变量,所以在python中,默认它的行为是创建局部变量,除非显式声明global,global定义的本地变量会变成其对应全局变量的一个别名...在d['b']=2这句中,它是“明确的”,因为如果把d当作是局部变量的话,它会报KeyError,所以它只能是引用全局的d,故不需要多此一举显式声明global。

1.8K70

解决UnboundLocalError: local variable time referenced before assignment

这个错误通常发生在在一个函数内部,尝试访问一个在函数内定义的局部变量之前。 这篇文章将详细介绍这个错误的原因,并提供几种常见的解决方法。...错误原因在Python中,当在函数内部定义了一个变量时,默认情况下,这个变量是局部变量。如果在函数内部尝试访问该变量之前对其进行赋值操作,就会触发UnboundLocalError。...这个错误的原因是因为Python在函数内部查找变量时,按照如下的顺序进行查找:在函数内部查找局部变量在函数外部查找全局变量在内置命名空间查找内置变量 如果在函数内部定义的变量前面出现了对该变量的赋值操作...在函数内部定义了局部变量 circumference,并将其返回给调用方。最后,我们打印出了计算得到的圆的周长。...结论UnboundLocalError: local variable 'xxx' referenced before assignment是由于在函数内尝试访问函数内定义的局部变量之前进行了赋值操作所引发的错误

1.7K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    一篇文章让你明白python的装饰器

    在看闭包问题之前先来看看关于python中作用域的问题 变量作用域 对于上述代码中出现错误,肯定没什么疑问了,毕竟b并没有定义和赋值,当我们把代码更改如下后: 再看一个例子: 首先这个错误已经非常明显:...说在赋值之前引用了局部变量b 可能很多人觉得会打印10然后打印6,其实这里就是涉及到变量作用域的问题 当Python编译函数的的定义体的时候,它判断b是局部变量,毕竟在函数中有b = 9表示给b赋值了,...我们对函数的定义是:一些可执行的代码,这些代码在函数定义后就确定了,不会在执行时发生变化,所以一个函数只有一个实例。...中使用 count += 1的时候其实就是count = count + 1,这样就是在averager函数定义体中对count进行赋值,count就变成了局部变量。...,下面就是装饰器,我个人觉得装饰器只是闭包的一种应用,闭包在很多情况下都是一种非常好的变成技巧 装饰器 关于装饰器本来是想重新整理一下,看了自己之前整理的博客,已经挺详细的,就把连接直接放这里了 http

    79510

    c++基础之变量和基本类型

    之前我写过一系列的c/c++ 从汇编上解释它如何实现的博文。从汇编层面上看,确实c/c++的执行过程很清晰,甚至有的地方可以做相关优化。...,则会执行默认初始化操作,全局变量会被赋值为0,局部变量则是未初始化的状态;它的值是不确定的。...如果将程序分为多个文件,则需要一种在文件中共享代码的方法。c++中这种方法是将声明与定义区分开来。在我之前的博客中,有对应的说明。...变量作用域 变量的作用域始于声明语句,终结于声明语句所在作用域的末端 局部变量在整个函数中有效 普通全局变量在整个程序中都有效果 花括号中定义的变量仅在这对花括号中有效 作用域可以存在覆盖,并且以最新的定义的覆盖之前的...,局部变量是在函数开始执行的时候为它分配内存,也就是说局部变量无法在编译期就得到它的地址,而全局变量是在程序加载的时候得到它的内存地址,复合常量表达式的要求 另外要注意,constexpr 不存在底层和顶层的现象

    1.6K30

    细微之处见真章之StringUtils的isBlank函数细节解读

    另外我们在研究这个问题的时候又有了新的发现: 我们发现 overlay 函数在此次提交时,将 StringBuilder 拼接的字符串的方式改为了直接用加号拼接,大家可以思考下为什么。...一个 final 变量,除非之前该变量是明确未被赋值,否则再次赋值会报编译时错误。 一旦 final 变量被赋值,那么它就是始终保持同一个值。...(注意:局部变量声明符包含初始化但不能是赋值表达式。) 它永远不会作为前缀或后缀递增或递减运算符的操作数出现。...2 局部变量声明时如果没有初始化,如果满足以下几种情况,则为 effectively final 没有声明为 final 当它出现在赋值表达式的左边时,它肯定是未赋值的,而且在赋值之前也没有明确赋值...; 也就是说,它绝对是未赋值的,也不是绝对赋值在赋值表达式的右边(§16(明确赋值))。

    73420

    Python程序员经常犯的10个错误,这些坑你踩过吗?

    在Python中,类变量在内部当做字典来处理,其遵循常被引用的方法解析顺序(MRO)。...上面的问题之所以会发生是因为当你给作用域中的一个变量赋值时,Python 会自动的把它当做是当前作用域的局部变量**,从而会隐藏外部作用域中的同名变量**。...很多人会感到很吃惊,当他们给之前可以正常运行的代码的函数体的某个地方添加了一句赋值语句之后就得到了一个 UnboundLocalError 的错误。...原因和之前那个例子的一样,不过更加令人难以捉摸。foo1 没有对 lst 进行赋值操作,而 foo2 做了。...此外,我们对 lst 进行的赋值操作是基于 lst 自身(这再一次被Python当成了局部变量),但此时还未定义。因此出错!

    54700

    Python函数式编程 入门必备

    这是因为,python 规则指定所有在赋值语句左面的变量都是局部变量,则在闭包 move() 中,变量 cordx 在赋值符号"="的左面,被 python 认为是 move() 中的局部变量。...再接下来执行 move() 时,程序运行至 cordx += x 时,因为之前已经把 cordx 归为 move() 中的局部变量了,因此,python 会在 move() 中去找在赋值语句右面的 cordx...通过使用语句 `nonloacal cordx' 显式的指定 cordx 不是闭包的局部变量,避免出现 UnboundLocalError. 4.2 容易犯错 函数式编程新手,包括我自己,经常会犯一个错误...不过,对于我们刚入门函数式编程,这个错误是最容易犯的,使用注意就是声明cordx为非局部变量。...原因: i 是闭包函数引用的外部作用域的变量, 只有在内部函数被调用的时候, 才会搜索变量i的值。 由于循环已结束, i指向最终值2, 所以各函数调用都得到了相同的结果。 如何解决这个问题?

    84630

    LinkedList源码最全面的分析

    集合拥有的方法,当我们熟知每个方法的用途和实现原理,在具体的场景应用中是不是有种得心应手,如数家珍的感觉,自信心得到了增长的同时,自己技术的增进又在潜移默化的过程中得到了提高,何乐而不为呢 1.2,分析源码的好处是...所以下面就一起把对应的方法分析了 //首先获取第一个节点引用first赋值给局部变量f,编程里这种手法很常用,你学会了吗?...的方法实现原理明白了,相信此时你更加明白了如何阅读一个源码的步骤,如何提高你的编程能力,当然了,你可能会自我怀疑,我学会了吗,我学到了什么?...那我接下来,我这里再次帮你梳理一下,你在源码分析的过程中得到了哪些收获吧 你懂得了如何编写可扩展的代码,即共用的方法可以进行抽取,抽成一个个可以复用的方法,这样你写的代码就具备了一定扩展性和健壮性,当然了...,你更加明白,在获取数据时,要进行前置校验,预检查操作,当不符合校验规则时,将错误抛给上层调用者,是不是和你日常开发一样的思路呢,学到了吧,于此同时,你也学会了,对一个方法的时间复杂度进行分析,当然了,

    43020

    【从零学习python 】31.深入理解Python中的高阶函数和闭包

    () 调用这个函数 demo()() # 我是demo里输入的内容 我是test函数里输入的内容 闭包 函数只是一段可执行代码,编译后就“固化”了,每个函数在内存中只有一份实例,得到函数的入口点便可以执行函数了...我们注意到一个问题:内嵌函数 inner 中引用到外层函数中的局部变量num,Python解释器会这么处理这个问题呢?...先让我们来看看这段代码的运行结果,当我们调用分别由不同的参数调用 outer 函数得到的函数时,得到的结果是隔离的(相互不影响),也就是说每次调用outer函数后都将生成并保存一个新的局部变量num,这里...UnboundLocalError: local variable 'num' referenced before assignment 原因分析 在python里,只要看到了赋值语句,就会认为赋值语句的左边是一个局部变量...num = num + 1 这段代码里,num 在=的左边,python解析器会认为我们要修改inner函数里num这个局部变量,而这个变量使用之前是未声明的,所以会报错。

    13010

    【C++】C++ 引用详解 ③ ( 函数返回值不能是 “ 局部变量 “ 的引用或指针 | 函数内的 “ 局部变量 “ 的引用或指针做函数返回值无意义 )

    一、函数返回值不能是 " 局部变量 " 的引用或指针 1、引用通常做右值 之前使用 引用 时 , 都是作为 右值 使用 , 引用只在 声明 的 同时 进行初始化时 , 才作为左值 , // 定义变量 a...int 为 0 就是成功 , int 为其它数值 , 就是错误码 ; 3、函数内的 " 局部变量 " 的引用或指针做函数返回值无意义 如果 想要 使用 引用 或 指针 作 函数的计算结果 , 一般都是将..., 返回 局部变量 的 地址 / 引用 是无意义的 , 一般 函数 只 返回一个 int 值 , 表示 该函数 是否执行成功 , 如果执行失败 , 返回错误码 ( 在哪一步执行失败 ) ; ----...如果 想要 在 函数中 , 返回 引用 / 指针 , 函数局部变量的 引用 / 指针 是返回不出来的 , 即使强行返回 引用 / 指针 , 也是当前 局部变量 被 分配的 栈内存 地址 , 该函数 执行完毕后..., 该 函数对应的 栈内存 会被回收 , 相应的 局不变量 地址 也有没有了意义 , 此时 , 再持有一个没有意义的 引用 / 指针 , 取出的值是随机无意义的值 ; 二、代码示例 - " 局部变量

    60420

    python 变量进阶(理解)

    ,本质上是 修改了数据的引用 变量 不再 对之前的数据引用 变量 改为 对新赋值的数据引用 1.2 变量引用 的示例 在 Python 中,变量的名字类似于 便签纸 贴在 数据 上 定义一个整数变量...:字典的 key 只能使用不可变类型的数据 注意 可变类型的数据变化,是通过 方法 来实现的 如果给一个可变类型的变量,赋值了一个新的数据,引用会修改 变量 不再 对之前的数据引用 变量 改为 对新赋值的数据引用...) 相同的内容 得到 相同的结果 不同的内容 得到 不同的结果 在 Python 中,设置字典的 键值对 时,会首先对 key 进行 hash 已决定如何在内存中保存字典的数据,以方便 后续 对字典的操作...在函数内部,可以 通过全局变量的引用获取对应的数据 但是,不允许直接修改全局变量的引用 —— 使用赋值语句修改全局变量的值 num = 10 def demo1(): print("demo1...print("demo2" + "-" * 50) print(num) demo1() demo2() print("over") 注意:只是在函数内部定义了一个局部变量而已,只是变量名相同

    75631

    Python每日一题:关于闭包

    test3(1) 学过其他语言,比如 Java ,对示例三的结果会比较惊讶,在 Java 中类似的情况,不会报错,会引用外部的全局变量,而如果在内部重新赋值后,再次使用则会用局部变量的值。...引用《流畅的Python》中对此的解释: 这不是缺陷,而是设计选择:Python 不要求声明变量,但是假定在函数定义体中赋值的变量是局部变量。...上段话第一次看可能会有点不明白,其实简单来说,Python 就是这样设计的,它认为在函数体中,如果对变量有赋值操作,则证明这个变量是一个局部变量,并且它只会从局部变量中去读取数据。...这样设计可以避免我们在不知道的情况下,获取到全局变量的值,从而导致一些错误数据的出现。 至于解决方法,就是使用 global 关键字,来说明我们使用的是 全局变量 。...这里报错的原因,请看第 1 点:变量的作用规则。因为 scores += val ,其实就是 scores = scores + val,有了赋值操作,则认为 scores 是局部变量了。

    51610

    【Python从入门到精通】(十二)Python函数的高级知识点,更深入的吸收知识【收藏下来保证有用!!!】

    当swap函数对a,b的值进行交换时,也就只影响到a,b的副本了,而对a,b本身没影响。但是对于列表,字典这两的数据类型的话,由于数据是存储在堆中,栈中只存储了引用,所以在修改形参数据时实参会改变。。...他的调用过程是层层递归的直到得到对里层的结果。然后反推得到外层的结果。 变量作用域 变量的作用域->说白了就是变量能作用的范围。Python中变量分两种:局部变量和全局变量。...其实我们期望在第四行打印全局变量name的值,但是由于第五行函数中定义了一个同名的局部变量name(Python语法规定,在函数内部对不存在的变量赋值时,默认就是重新定义新的局部变量)。...在函数中通过 global关键字声明全局变量,为了避免在函数中对全局变量赋值(不是重新定义局部变量),可使用global语句来声明全局变量。...通过global 修饰全局变量之后,在同名的局部变量定义之前,都使用的是全局变量。 函数的高级用法 函数赋值给其他变量 函数不仅仅可以直接调用,还可以直接将函数赋值给其他变量。

    68730

    聊聊并发编程:final关键字

    1.2 局部变量 对于局部变量使用final,理解就更简单,局部变量的仅有一次赋值,一旦赋值之后再次赋值就会出错: 1.3 基本数据类型 VS 引用数据类型 上面讨论的基本都是基本数据类型,基本数据类型一旦赋值之后...在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。...我们先假设线程B读对象引用与读对象的成员域之间没有重排序,那以下是一种可能的执行时序: 这里可以看出, 写普通域的操作被编译器重排序到了构造函数之外,读线程B错误地读取了普通变量i初始化之前的值。...要得到这个效果,还需要一个保证:在构造函数内部,不能让这个被构造对象的引用为其他线程所见,也就是对象引用不能在构造函数中“逸出”。...对于引用类型,写final域的重排序规则对编译器和处理器增加了如下约束:在构造函数内对一个final引用的对象的成员域的写入,与随后在构造函数外把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序

    17930

    一点一滴探究JVM之内存结构

    这也就能回答开头我们看到的那个问题了,很简单错误在单线程情况下肯定是StackOverFlowError,多线程下OutOfMemoryError(上图已经写得很清楚了) 比如 public void...当进入一个方法时,这个方法需要在栈中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。 操作数栈: 操作数栈又常被称为操作栈,操作数栈的最大深度也是在编译的时候就确定了。...当一个方法开始执行时,它的操作栈是空的,在方法的执行过程中,会有各种字节码指令(比如:加操作、赋值元算等)向操作栈中写入和提取内容,也就是入栈和出栈操作。...(在方法区中,后面介绍)中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。...方法返回地址: 当一个方法被执行后,有两种方式退出该方法:执行引擎遇到了任意一个方法返回的字节码指令或遇到了异常,并且该异常没有在方法体内得到处理。

    1.4K00

    java与C++变量初始化的对比

    java尽力保证:所有变量在使用前都能得到恰当的初始化 ①函数/方法局部变量的初始化 在C/C++中,变量的初始化还是得依赖于程序员的自觉性。...而在java中,对于方法的局部变量,java以编译时错误来保证变量在使用前都能得到恰当的初始化。...在指定初始化之前,编译器还会为这些数据成员进行默认初始化,实际上是把刚分配的对象内存都置零。...也就是说下面的i经历过被初始化为0后,再赋值为999的过程。...java尽力保证:所有变量在使用前都能得到恰当的初始化(《java编程思想》) java在变量初始化上,普通变量以编译错误、成员变量以默认初始化等手段,尽力使所有的变量在使用前都可得到初始化,在安全性上大大强于

    1K30

    C语言基础知识梳理总结

    大家好,又见面了,我是你们的朋友全栈君。 C语言是当代人学习及生活中的必备基础知识,应用十分广泛,下面为大家带来C语言基础知识梳理总结,C语言零基础入门绝对不是天方夜谭!...4、如果被调用的函数定义出现在主调函数之前可以不必声明。   5、如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明。...其中需要说明的是在定义局部变量不赋初值的话,则静态局部变量编译时自动赋值为0或者空字符,虽然静态局部变量在函数调用结束后仍然存在,但是其他函数不能引用它的。...静态局部变量主要用在当初始化后,变量只是被引用而不改变其值。...extern声明外部变量,用以扩展外部变量的作用域。在一个文件中,如果定义之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量做外部变量声明。

    78610

    JavaScript闭包,只学这篇就会了

    程序员都能理解上面代码中一个函数的引用是如何被赋值给一个变量(say2)的。...在JavaScript中,如果在一个函数中定义了另外一个函数,即使从被调用的函数中返回,局部变量依然能够被访问到。正如上面例子中我们在得到sayHello()的返回值之后又调用了say2()一样。...这个匿名函数能够引用值为Hello Bob的变量text是因为sayHello2()的局部变量被保留在了闭包中。...因为我们从0开始计数所以item的值为item2,而i++会使i的值变为3。 下面这个例子展示了闭包在退出之前包含了外部函数中定义的任何局部变量。注意到变量alice其实是在匿名函数之后定义的。...在函数中定义多层函数是有可能的,这样你就可以得到多个级别的闭包。

    75580

    C++知识总结

    (3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处...因为随着该局部变量生存期的结束,相应的引用也会失效,产生runtime error! 注意: (1)不能返回局部变量的引用。这条可以参照Effective C++[1]的Item 31。...根据前面提到的引用作为返回值的三个规则,第2、3两个方案都被否决了。静态对象的引用又因为((a+b) == (c+d))会永远为true而导致错误。...“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小; 7....对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。 13.虚函数的使用方法是: 在基类用virtual声明成员函数为虚函数。

    1K40
    领券