有的,难道你不觉得奇怪吗?报错是变量未初始化,而不是变量未定义。 题目中函数内 c= c+1 就已经表明了声明的变量 c 是属于局部变量的。...按理说,先执行赋值语句右侧,而此时 c 并没有声明,应该在全局环境命中才对啊。所以想象中的结果应该是局部变量 c = 2 而全局变量的 c 保持原值。 但是,这只都是想当然。...讲了这么多其实我是想引出,python虽然是动态语句,但它还是会对代码做扫描工作的,会有收集有用的静态信息。...__code__.co_varnames) # (‘c’, ‘a’) 因此,函数test在执行前,变量 c 就已经被声明在局部变量环境中了,而不是我们自认为的当赋值语句运行后才会在局部变量里。...于是,这就导致了报错信息是变量未初始化而不是变量未定义。 ====== 分割线 ========= 题主评论要求: 关于变量的初始化,定义,创建这三者关系,能帮忙疏导一下理解吗?
之所以说这个问题重要,是因为它可以实现一些灵活的动态赋值的功能。 它们都是字典类型,用法不需多言。...然而,在使用过程中,有一个陷阱需要注意:globals() 可读可写,而 locals() 只可读却不可写。今天分享的文章,就是在探究这个问题,写得很深入,特分享给大家。...于是, 我们也就能通过这些方法去实现我们"动态赋值"的需求....但事实真是如此吗? 不是!...这也就是为什么, 当我们通过locals()[i] = 1的方式去动态赋值时, print a却触发了NameError异常, 而相反的, globals()确实真正的全局命名空间, 所以一般会说: locals
在工作中, 有时候会遇到一种情况: 动态地进行变量赋值, 不管是局部变量还是全局变量, 在我们绞尽脑汁的时候, Python已经为我们解决了这个问题....Python的命名空间通过一种字典的形式来体现, 而具体到函数也就是locals() 和 globals(), 分别对应着局部命名空间和全局命名空间....于是, 我们也就能通过这些方法去实现我们"动态赋值"的需求....但事实真是如此吗? 不是!...这也就是为什么, 当我们通过locals()[i] = 1的方式去动态赋值时, print a却触发了NameError异常, 而相反的, globals()确实真正的全局命名空间, 所以一般会说 locals
沿着它的动态特性话题,猫哥有几篇文章依次探及了:动态修改变量、动态定义函数、动态执行代码等内容,然而,当混合了变量赋值、动态赋值、命名空间、作用域、函数的编译原理等等内容时,问题就可能会变得非常棘手。...在某些编程语言中,变量的声明与赋值是可以分开的,例如在声明时写 int a ,需要赋值时,再写 a = 1 ,当然也可不拆分,则是 int a = 1 。...关于 locals() 的创建过程,在《Python 动态赋值的陷阱》文中有所分析,locals() 字典是局部命名空间的代理,它会采集局部作用域的变量,代码运行期若动态修改局部变量,只会影响该字典,并不会影响真正的局部作用域的变量...在创建 locals() 字典时,由于局部作用域内有变量 y 的声明,因此我们首先在其中采集到了 y,而不必在 exec() 函数的动态结果中查找。...矛盾出现了,这里有点绕,我们理一下:左侧的 y 等着完成赋值,因此需要右侧的执行结果;而右侧的字典需要使用到 y 的值,因此就依赖着左侧的 y 完成赋值。
看来刚才“有些函数并不是真的是函数”的说法有些不公平了。 参数魔法 函数使用起来简单,创建起来也并不复杂。但函数参数的用法有时候就有些神奇了。...写在def语句中函数名后面的变量通常叫做函数的形参(parameter),而调用函数的时候提供的值是实参(argument)或者成为参数。 我能改变参数吗?...我猜想 位置参数和位置肯定有关系,当使用它时,它会默认赋值给它位置对应的参数,那么,这里就是greeting。所以呢,这里才会赋值两次。...可以把它们看作是值的名字。在执行x=1赋值语句后,名称x引用到值1.这就像用字典一样,键引用值,当然,变量和所对应的值用的是个“不可见”的字典。实际上这么说已经很接近真实情况了。...外部作用域的变量一般是不能进行重新绑定的。但是python3中,nonlocal关键字被引入。它和global关键字的使用方式类似,可以让用户对外部作用域(但并非全局作用域)的变量进行赋值。
为什么 join()是一个字符串方法而不是列表或元组方法? 异常有多快? 为什么Python中没有switch或case语句? 难道不能在解释器中模拟线程,而非得依赖特定于操作系统的线程实现吗?...为什么必须在方法定义和调用中显式使用“self”? 这个想法借鉴了 Modula-3 语言。出于多种原因它被证明是非常有用的。 首先,更明显的显示出,使用的是方法或实例属性而不是局部变量。...在函数体中赋值的那些变量(并且没有明确声明为全局)赋值,就必须以某种方式告诉解释器一个赋值是为了分配一个实例变量而不是一个局部变量,它最好是通过语法实现的(出于效率原因)。...因此,使用lambda而不是本地定义的函数的唯一优点是你不需要为函数创建一个名称 -- 这只是一个分配了函数对象(与lambda表达式生成的对象类型完全相同)的局部变量!...换句话说,应该使用 == 来比较字典键,而不是使用 is 。 使用列表作为键时进行复制。这没有用的,因为作为可变对象的列表可以包含对自身的引用,然后复制代码将进入无限循环。
使用list工厂函数 为了创建一个a的拷贝,可以使用list工厂函数,这也是Python Cookbook中的推荐做法。...除了使用工厂函数,切片也可以达到同样的效果: Python >>> b = a[:] >>> b is a False 使用copy模块 一切看起来都很美好,真的是这样吗?...列表作为函数参数 参数的默认值 python的函数参数传递方法都是引用传递,而不是值传递,对于列表与字典这种可变类型就要特别小心了,可能会出现以下的错误: Python >>> def foo(a=[]...所以,要避免使用列表或字典作为函数的默认参数。...,我们希望整体更新列表,比如去重操作array = list(set(array),这时用上面的方法就不行了,因为这里创建了一个新的列表list(set(array))并将其引用重新赋给了array,而函数内的局部变量
但是,它的本质仍然是一个对象,于是乎你可以对它做如下的操作: 你可以将它赋值给一个变量 你可以拷贝它 你可以为它增加属性 你可以将它作为函数参数进行传递 如下示例: In [39]: class ObjectCreator...动态地创建类 因为类也是对象,你可以在运行时动态的创建它们,就像其他任何对象一样。首先,你可以在函数中创建类,使用 class 关键字即可。...使用type创建带有方法的类 最终你会希望为你的类增加方法。只需要定义一个有着恰当签名的函数并将其作为属性赋值就可以了。...你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。...现在你想知道那为什么 type 会全部采用小写形式而不是 Type 呢?好吧,我猜这是为了和 str 保持一致性,str是用来创建字符串对象的类,而 int 是用来创建整数对象的类。
人生苦短,我学Python!在Python中,每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。变量名应该清晰地表达其用途或含义,避免使用无意义的名称。...基本规则和意义 命名的初心 想象一下,如果代码是你的美食笔记,变量就是那些调料的名字。你想让未来的自己,或是别人,一眼就能知道“salt”是盐,“pepper”是胡椒,而不是什么“x123”。...# 正确的是使用其他名字 loop_count = 5 见名知意 好的变量名应该能让人快速理解其用途。比如,total_price而不是tp。...利用注释 如果变量名真的很难表达清楚,那就加上注释来辅助说明吧!...= name # 实例变量 使用枚举类型(Enum) 对于一组固定的值,使用枚举类型可以提高代码的可读性和安全性。
_pi 是可以导入的 不点名不能用吗?...o 是 变量标识符 而不是 字符串 如果加了双引号 就是字符串了 在等号两端 都保留 有一个空格 可是 为什么要 加空格呢?...locals() 查询本地变量 有一个内置的函数叫做 locals 可以查询关于 locals 的帮助 返回的是一个包含当前域中所有变量的字典 声明和赋值都使用等号 声明并赋值...变量o 之后 变量o 真的在内存里有位置了么?...里面 第二次赋值 和 第一次赋值 有什么区别吗?
我们知道 Golang 中变量的赋值不是并发安全的,实际情况果真如此吗? 1.什么是并发安全 并发安全就是程序在并发情况下执行的结果是正确的。...2.struct 并发赋值安全吗 对一个简单变量的自增都会出现偏差,那么赋值一个更为复杂的结构体会不会有问题呢?...例如以下代码,在多协程的情况下,并发使用两个不同的值对结构体变量进行赋值,如果结构体成员出现异常情况, 那么说明并发出现了问题。...不过我这里想说的不是次数的问题,因为次数多少是个概率的问题,我这里说的是和所要赋的值有关。只要不同的值满足一定特点,不管多少次并发,都是安全的。...、通道、接口(不安全) 数组、切片、字典、通道、接口,这些复合类型,除了数组,其他底层数据结构都是 struct,所以并发都不是安全的,当然数组并发赋值也是不安全的。
可迭代对象,迭代器,生成器,相信许多学习Python的小伙伴或多或少都听说过,但你真的知道他们的区别吗?真的知道为什么需要这些概念吗?...- 生成器为什么不能重复使用? - Python的动态协议,不一样的迭代实现。...- 第一次遍历时,会问迭代器拿一个元素,然后把元素赋值给变量 n 。 - 整个过程,iter 执行了一次,next 执行了4次。 - 之前说的状态值 i ,其实就保存在迭代器中。...生成器其实就是一种迭代器 所谓的生成器,指定的是一种不断生成输出东西的事物,同样地可以通过 next 方法从生成器上获取输出。 是不是与迭代器的概念不谋而合?那又是为什么弄这样的一个概念出来?...真的需要 `__iter__` 才是可迭代对象吗?
前言 可迭代对象,迭代器,生成器,相信许多学习Python的小伙伴或多或少都听说过,但你真的知道他们的区别吗?真的知道为什么需要这些概念吗?...- 生成器为什么不能重复使用? - Python的动态协议,不一样的迭代实现。...- 第一次遍历时,会问迭代器拿一个元素,然后把元素赋值给变量 n 。 - 整个过程,iter 执行了一次,next 执行了4次。 - 之前说的状态值 i ,其实就保存在迭代器中。...生成器其实就是一种迭代器 所谓的生成器,指定的是一种不断生成输出东西的事物,同样地可以通过 next 方法从生成器上获取输出。 是不是与迭代器的概念不谋而合?那又是为什么弄这样的一个概念出来?...真的需要 `__iter__` 才是可迭代对象吗?
看以下代码时,以Model为中心,而不是以dic中的数据为中心。...,进而对数组中每个模型遍历并字典转模型,但是我们不知道数组中的模型都是什么类型,我们可以声明一个方法,该方法目的不是让其调用,而是让其实现并返回模型的类型。...这块语言可能解释不太清楚,可以参考我的demo,直接运行即可。...// 如果模型属性数量大于字典键值对数理,模型属性会被赋值为nil而报错 if (value == nil) continue; // 获得成员变量的类型...#这里写成一个方法,而不是写死,也是方便代码封装后继承重写复用。
为什么必须在方法定义和调用中显式使用“self”? 这个想法借鉴了 Modula-3 语言。出于多种原因它被证明是非常有用的。 首先,更明显的显示出,使用的是方法或实例属性而不是局部变量。...在函数体中赋值的那些变量(并且没有明确声明为全局)赋值,就必须以某种方式告诉解释器一个赋值是为了分配一个实例变量而不是一个局部变量,它最好是通过语法实现的(出于效率原因)。...因此,使用lambda而不是本地定义的函数的唯一优点是你不需要为函数创建一个名称 -- 这只是一个分配了函数对象(与lambda表达式生成的对象类型完全相同)的局部变量!...换句话说,应该使用 == 来比较字典键,而不是使用 is 。 使用列表作为键时进行复制。这没有用的,因为作为可变对象的列表可以包含对自身的引用,然后复制代码将进入无限循环。...如果有一个名为 "x" 的全局变量,它是否会在with块中使用?如您所见,Python的动态特性使得这样的选择更加困难。
本方法是直接使用一个sign变量作为标志,并且直接作为while循环的判断条件。如果标志为真执行循环,如果输入等于“结束”,标志循环重新赋值为假,则循环判断条件不通过,停止循环语句。...是不是还是执行了4次,和之前没有本质的区别,有什么方法可以立即执行while循环判断吗?...如果平时编程真的无意间弄了个无限循环,可以按Ctrl+C强制退出! 在这里我们使用的是break退出循环!循环执行到break的时候会毫不犹豫,直接退出循环的!...为了更好地体现缩进的关系,接下来我用jupyter编辑器和大家分享,其实目前的所有编程都可以用IDLE实现,所以基础课程,非必要我都会继续用IDLE截图!...就酱~下期继续聊聊while和列表和字典的那些事!
为什么必须在方法定义和调用中显式使用“self”? 这个想法借鉴了 Modula-3 语言。出于多种原因它被证明是非常有用的。 首先,更明显的显示出,使用的是方法或实例属性而不是局部变量。...在函数体中赋值的那些变量(并且没有明确声明为全局)赋值,就必须以某种方式告诉解释器一个赋值是为了分配一个实例变量而不是一个局部变量,它最好是通过语法实现的(出于效率原因)。...因此,使用 lambda 而不是本地定义的函数的唯一优点是你不需要为函数创建一个名称 -- 这只是一个分配了函数对象(与 lambda 表达式生成的对象类型完全相同)的局部变量! 13....换句话说,应该使用 == 来比较字典键,而不是使用 is 。 使用列表作为键时进行复制。这没有用的,因为作为可变对象的列表可以包含对自身的引用,然后复制代码将进入无限循环。...如果有一个名为 "x" 的全局变量,它是否会在 with 块中使用?如您所见,Python 的动态特性使得这样的选择更加困难。
为什么必须在方法定义和调用中显式使用“self”? 这个想法借鉴了 Modula-3 语言。出于多种原因它被证明是非常有用的。 首先,更明显的显示出,使用的是方法或实例属性而不是局部变量。...在函数体中赋值的那些变量(并且没有明确声明为全局)赋值,就必须以某种方式告诉解释器一个赋值是为了分配一个实例变量而不是一个局部变量,它最好是通过语法实现的(出于效率原因)。...因此,使用 lambda 而不是本地定义的函数的唯一优点是你不需要为函数创建一个名称 -- 这只是一个分配了函数对象(与 lambda 表达式生成的对象类型完全相同)的局部变量! 13....换句话说,应该使用 == 来比较字典键,而不是使用is 。 使用列表作为键时进行复制。这没有用的,因为作为可变对象的列表可以包含对自身的引用,然后复制代码将进入无限循环。...如果有一个名为 "x" 的全局变量,它是否会在 with 块中使用?如您所见,Python 的动态特性使得这样的选择更加困难。
领取专属 10元无门槛券
手把手带您无忧上云