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

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

在看闭包问题之前先来看看关于python中作用域的问题 变量作用域 对于上述代码中出现错误,肯定没什么疑问了,毕竟b并没有定义和赋值当我们把代码更改如下后: 再看一个例子: 首先这个错误已经非常明显:...说赋值之前引用了局部变量b 可能很多人觉得会打印10然后打印6,其实这里就是涉及到变量作用域的问题 当Python编译函数的的定义体的时候,它判断b是局部变量,毕竟在函数中有b = 9表示给b赋值了,...所以python会从本地环境获取b,当我们调用方法执行的时候,定义体会获取并打印变量a的值,但是当尝试获取b的值的时候发现b没有绑定值,所以要想让上述代码运行还可以把b设置为全局变量,或者把b赋值放到调用之前...这里有一个词:引用环境,其实引用环境就是执行运行的某个时间点,所有处于活跃状态的变量所组成的集合,这里的变量是指变量的名字和其所代表的对象之间的联系。...: 这个例子中和我们上面使用的不同之处是:这里的count和total是数字,是不可变类型,而之前的例子中series是一个列表是可变类型 所以这里重新回到了最开始说的作用域问题了,当我averager

75810

Python | 十个Python程序员易犯的错误

上述错误的出现,是因为当你某个作用域内为变量赋值,该变量Python解释器自动视作该作用域的本地变量,并会取代任何上一层作用域中相同名称的变量。...请看下面这个代码示例: ? ? 呃?为什么函数foo1运行正常,foo2却出现了错误? 答案与上一个示例相同,但是却更难捉摸清楚。foo1函数并没有为lst变量进行赋值,但是foo2却有赋值。...我们知道,lst += [5]只是lst = lst + [5]的简写,从中我们就可以看出,foo2函数尝试为lst赋值(因此,Python解释器认为是函数本地作用域的变量)。...那么回到我们的示例,当我们导入a.py模块,它在引用b.py模块是不会出现问题的,因为b.py模块在被引用时,并不需要访问a.py模块中定义的任何变量或函数。...下面这段代码就使用了这种方法,因此Python 2和Python 3中的输出结果是一致的: ? Python 3运行代码: ? 太棒了!

1.4K100
您找到你想要的搜索结果了吗?
是的
没有找到

Python程序员最常犯的十个错误,看完你自己都笑了

上述错误的出现,是因为当你某个作用域内为变量赋值,该变量Python解释器自动视作该作用域的本地变量,并会取代任何上一层作用域中相同名称的变量。...请看下面这个代码示例: 呃?为什么函数foo1运行正常,foo2却出现了错误? 答案与上一个示例相同,但是却更难捉摸清楚。foo1函数并没有为lst变量进行赋值,但是foo2却有赋值。...我们知道,lst += [5]只是lst = lst + [5]的简写,从中我们就可以看出,foo2函数尝试为lst赋值(因此,Python解释器认为是函数本地作用域的变量)。...那么回到我们的示例,当我们导入a.py模块,它在引用b.py模块是不会出现问题的,因为b.py模块在被引用时,并不需要访问a.py模块中定义的任何变量或函数。...这样的话,当你的程序执行完成之后(即正常退出程序的情况),你所指定的处理程序就会在解释器关闭之前运行

1.1K40

十个 PHP 开发者最容易犯的错误

当 $value 通过赋值获得, foreach 按顺序复制每个 $array 的元素到 $value ,第二个 foreach 里面的细节是这样的 第一步:复制 $array[0] (也就是 1 )...所以 $array 现在包含 [1, 2, 2] 为了 foreach 中方便的使用引用而免遭这种麻烦,请在 foreach 执行完毕后 unset() 掉这个保留着引用变量。...考虑到这一点,让我们重新回顾一以上例子中的两个关键行: // getValues() 返回了一个 $values 数组的拷贝 // 所以`test`元素添加到了这个拷贝中,而不是 $values 数组本身...既然 $_POST 是一个超级全局变量,如果我们重写 一次 (我们的脚本里尽可能早的),修改的值(包括 POST 的有效内容)将可以我们的代码引用。...最乐观的预计,前后代码不一致(在此之前每个开发者都在“做自己的事情”)。但最差的结果,PHP 代码不能运行或者很难(有时是不可能的)去顺利通过,这对于 调试代码、提升性能、维护项目来说也是困难重重。

3K90

十个 PHP 开发者最容易犯的错误

当 $value 通过赋值获得, foreach 按顺序复制每个 $array 的元素到 $value ,第二个 foreach 里面的细节是这样的 第一步:复制 $array[0] (也就是 1 )...所以 $array 现在包含 [1, 2, 2] 为了 foreach 中方便的使用引用而免遭这种麻烦,请在 foreach 执行完毕后 unset() 掉这个保留着引用变量。...考虑到这一点,让我们重新回顾一以上例子中的两个关键行: // getValues() 返回了一个 $values 数组的拷贝 // 所以`test`元素添加到了这个拷贝中,而不是 $values 数组本身...既然 $_POST 是一个超级全局变量,如果我们重写 一次 (我们的脚本里尽可能早的),修改的值(包括 POST 的有效内容)将可以我们的代码引用。...最乐观的预计,前后代码不一致(在此之前每个开发者都在“做自己的事情”)。但最差的结果,PHP 代码不能运行或者很难(有时是不可能的)去顺利通过,这对于 调试代码、提升性能、维护项目来说也是困难重重。

2.6K50

易犯错误 | 十个 PHP 开发者最容易犯的错误

所以 为了 foreach 中方便的使用引用而免遭这种麻烦,请在 foreach 执行完毕后 unset() 掉这个保留着引用变量。...考虑到这一点,让我们重新回顾一以上例子中的两个关键行: // getValues() 返回了一个 $values 数组的拷贝 // 所以`test`元素添加到了这个拷贝中,而不是 $values...$res = $connection->query("SELECT `x`,`y` FROM `test` LIMIT $limitFrom, $portionSize"); } 当我们把这个常见错误和上面的...既然 _POST 是一个超级全局变量,如果我们重写 一次 (我们的脚本里尽可能早的),修改的值(包括 POST 的有效内容)将可以我们的代码引用。...一个项目中忽视代码规范能够导致大量的问题。最乐观的预计,前后代码不一致(在此之前每个开发者都在“做自己的事情”)。

4.5K20

这一次,让你彻底理解Java的值传递和引用传递!

7 func(a); 8} 例子中 int a=10;中的a在被调用之前就已经创建并初始化,调用func方法,他当做参数传入,所以这个a是实参。...Java的数据类型 所谓数据类型,是编程语言中对内存的一种抽象表达方式,我们知道程序是由代码文件和静态资源组成,程序运行前,这些代码存在在硬盘里,程序开始运行,这些代码会被转成计算机能识别的内容放到内存中被执行...1weight=40; 当代码中重新给weight变量进行赋值,JVM会去栈中寻找字面量为40的内容,发现没有,就会开辟一块内存空间存储40这个内容,并且把weight指向这个地址。...引用数据类型的存储: 上面提到:堆是用来存储对象本身和数组,而引用(句柄)存放的是实际内容的地址值,因此通过上面的程序运行图,也可以看出,当我们定义一个对象 1Person per=new Person...变量执行per=new Person(),JVM会创建一个Person类的实例对象并在堆中开辟一块内存存储这个实例,同时把实例的地址值赋值给per变量

69210

【C语言】万字速通初阶指针 zero → One

因为指针变量是指向一个变量的地址,所以将一个变量的地址值 赋值这个指针就 "指向" 了该变量 例如:将变量 i 的地址值赋值给指针变量 p 中,p 就指向 i,其关系如下所示↓ 程序代码中是通过...---- 赋值语句的方法 如下代码所示↓ int a; int *p; p= &a; 不允许把一个数赋予指针变量,故下面的赋值错误的。...int * p; p = 10; 赋值的指针变量前不能再加“*”说明符,如写为 *p=&a 也是错误的。...two pa = 0  ---- 指针使用之前检查有效性 当你指针变量不可以用的时候就把它设置成NULL,当你指针变量可以用的时候就不是NULL 当我们对这个指针进行初始化的话,那么它就是有效的...所以,在这个 * 的前面,还是需要写上int*。*ppa 是一个指针,而int*是所指向的指针变量。于是就是 int** ppa,这种的话也称之为是:二级指针。

1.2K50

【C++修炼之路】1. 初窥门径

因为C++兼容C语言的用法,这些又用得不是很多,因此,当我们需要控制格式以及精度,仍然可以利用printf形式输出。...,发现a变量可以同时多个引用,注释的代码去掉注释后,就会产生报错,因为没有初始化,就相当于起小名但是不知道是给谁取小名,这个小名变的毫无意义。...然而,d赋值给int类型的a底层会发生强转,即double类型强转成int类型,这就涉及到一个新的知识,强转赋值的时候,并不是直接把d取整赋值给a,而是会产生一个临时的变量来储存d强转后的结果并且赋值给...a的也是这个临时变量这个临时变量具有常性,不能修改,因此,下一行注释掉的代码错误的类型出错不是double变int,而是const int 不能int直接接受,这属于权限放大,所以最后一行代码前面加上...好,上面的总结经验已经分享给大家,接下来看看release运行结果是这样: 因为release版本运行会优化代码程序,会将一些错误进行避免,但对于我们来说,debug环境才是真正的程序结果。

1K00

web选手如何快速卷入二进制世界

1 F5伪C代码 通常我们不会直接去看冗长的汇编代码,为了方便快速的大致了解程序逻辑可以使用F5快捷键汇编界面的时候按一F5就会额外打开一个新的伪代码页面,如下图: 这些代码并不是真正的C代码,只是...另外我们还经常会想知道某个函数在哪里哪些函数调用,这个ida里叫做交叉引用。通过单击想要查找的函数然后按快捷键X,就会弹出其交叉引用列表,然后你去选择要看哪个就行。...比如我们搜索“cmd”: 找到我们感兴趣的字符串然后双击 单击前面那个,直接认为是一个变量得了,同样的按X用交叉引用就能找到这个字符串哪里引用了: 再双击交叉引用的项就能跳到具体代码了,注意跳过去通常是汇编...复制到ubuntu后,chmod+x然后运行 这样就行了,调试服务端就完成了,接下来ida里配置一debugger 接下来就回到之前的调试了,start process也行,attache也行...这里建议先本地静态分析一对应的二进制文件,然后再设置其远程linux调试,直接startprocess,这样似乎就可以使用伪代码来单步调试了 效果: ubuntu调试服务端还能看到打印出来了运行程序的日志信息

21420

Java-值传递和值引用

2.Java的数据类型 我们知道程序是由代码文件和静态资源组成,程序运行前,这些代码存在在硬盘里,程序开始运行,这些代码会被转成计算机能识别的内容放到内存中被执行。...局部变量可以理解为:方法中定义的变量 你比如我们代码中写了一个局部变量number并赋值 public void method(){ int number=8; } 那么这个局部变量会被分两步存储栈中...mPerson变量执行mPerson=new Person(),JVM会创建一个Person类的实例对象并在堆中开辟一块内存存储这个实例,同时把实例的地址值赋值给mPerson变量。...那我们在对上面的代码稍作变动执行一: 代码: ? image.png 结果: ?...无论是基本类型和是引用类型,实参传入形参,都是值传递,也就是说传递的都是一个副本,而不是内容本身。 上面的代码可以用下图表示: ?

1.6K30

jvm类加载机制

这里还有一注意点: 对基本数据类型来说,对于类变量(static)和全局变量,如果不显式地对其赋值而直接使用,则系统会为其赋予默认的零值,而对于局部变量来说,使用前必须显式地为其赋值,否则编译不通过...对于同时static和final修饰的常量,必须在声明的时候就为其显式地赋值,否则编译不通过;而只final修饰的常量则既可以声明时显式地为其赋值,也可以类初始化时显式地为其赋值,总之,使用前必须为其显式地赋值...,定义它之后的变量,在前面的静态语句块可以赋值,但是不能访问。...执行结果,创建对象先执行顺序: 父类的静态块 子类的静态块 父类的成员变量,实例代码块,构造函数 子类的成员变量,实例代码块,构造函数, 明白这个这段代码的执行结果就很好理解了。...补充说明:本文后半部分一直介绍类初始化,其实跟类得出事化相仿还有对象初始化,只不过一般情况类初始化发生对象初始化之前(可以理解为:类生命周期中类初始化之后是使用阶段,当在代码里中有new操作就会发生对象初始化操作

27140

Python程序员最常犯的十个错误

上述错误的出现,是因为当你某个作用域内为变量赋值,该变量Python解释器自动视作该作用域的本地变量,并会取代任何上一层作用域中相同名称的变量。...我们知道,lst += [5]只是lst = lst + [5]的简写,从中我们就可以看出,foo2函数尝试为lst赋值(因此,Python解释器认为是函数本地作用域的变量)。...那么回到我们的示例,当我们导入a.py模块,它在引用b.py模块是不会出现问题的,因为b.py模块在被引用时,并不需要访问a.py模块中定义的任何变量或函数。...因为当解释器结束运行的时候,该模块的全局变量都会被设置为None。因此,在上述示例中,当__del__方法调用之前,foo已经设置成了None。...这样的话,当你的程序执行完成之后(即正常退出程序的情况),你所指定的处理程序就会在解释器关闭之前运行

96470

python模块与包揭秘

之前提到过,其实import也是执行了一个赋值操作,它把我们需要导入的目标模块对象赋值给了对应的变量名,例如上例就是把math模块对象赋值给了math这个变量名,然后math所指向的模块对象中的内容...这里写图片描述 之前还真遇到一个与搜索路径相关的一个bug,当时自己也是啥都不懂(加上有点脑残),也没学python,就随便编写了一个文件保存为random.py,然后这个文件中有这么一段代码: import...本来是很简单的代码,但是就是报错,提示就是random模块没有choice这个方法,当时纠结了好久,真的是脑残,现在大家应该不会再犯这种错误了吧。...这个差异就体现在,通过from导入的变量名(不应该说是变量名,但是不知道怎么形容更好),在当前文件中可以直接访问,不需要再通过先前说的【模块名.属性】的形式,例如上面的例子用from语句重写: from...中默认先搜索当前目录,然后再去pythonpath里寻找,所以当程序执行到import string,先找到了自己写的string.py。

47010

python函数作用域与闭包

函数的定义 python中,是用def来创建一个函数,实际上def只是完成了一个类似与赋值的操作---------把一个函数对象赋值给一个变量名,还记得我们之前说过python中变量名只是一个标识符...这个引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。...闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。 ---- 上面提到了两个关键的地方: 自由变量 和 函数, 这两个关键稍后再说。...还是赘述“闭包”的意思,望文知意,可以形象的把它理解为一个封闭的包裹,这个包裹就是一个函数,当然还有函数内部对应的逻辑,包裹里面的东西就是自由变量,自由变量可以随着包裹到处游荡。...当然还得有个前提,这个包裹是创建出来的。 通过Python的语言介绍一,一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包。

54320

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

其二,提高你对java的理解,知道你创建的每一个对象,每一个变量,都在什么地方,如果不知道这些稀里糊涂代码,总会有一天会”翻车”的!好了,废话不多说了,我们开始正题吧!...test() { String name = "stormma"; int age = 21; } 上面的例子的age变量和name引用都是存储虚拟机栈的栈帧里面的(因为我们前面说过了...局部变量表所需的内存空间在编译期间完成计算的,即在Java程序编译成Class文件,就确定了所需分配的最大局部变量表的容量。...当进入一个方法这个方法需要在栈中分配多大的局部变量空间是完全确定的,方法运行期间不会改变局部变量表的大小。 操作数栈: 操作数栈又常被称为操作栈,操作数栈的最大深度也是在编译的时候就确定了。...这个概念我们之后的文章会进行详细的讲解,如果你特别好奇,可以看一之前的文章, Java逃逸分析)!也是jvm管理的最大一块内存(对了,上面的图的大小不代表内存占比,只是为了看着舒服而已)!

1.4K00

java作用域-翻译:⚡⛓️可视化的 JavaScript作用域(链)

当执行上下文创建,作用域链就被创建了,这意味着它是在运行时()创建的。   然而,在这篇文章中不会讨论 Object 和执行上下文( ),让我们只关注作用域(Scope)。   ...下面的代码中,执行上下文中的键值对(Key/Value pairs)代表了作用域链对变量引用。   ...全局执行上下文(global )中的作用域中引用了 3 个变量:   本地执行上下文(local )中,我们引用了两个变量:   当我们尝试函数 中访问变量, 引擎首先在本地作用域链(local...(好吧,这可能会引起混乱,有些人会反过来理解“上”和“”的意思。重新表述一:你可以向外部作用域查找,但不能向内部作用域查找)。喜欢把这个过程想象成一个瀑布。   ...甚至可以有更多层次:   让我们以这段代码为例:   跟之前代码很相似,只是有两点不同:我们函数中声明了变量city,而不是全局作用域中声明。而且,我们没有调用函数,所以也没有创建本地上下文。

45620

一道简单的sql语句题

继续运行面的代码,结果如下: ?...融360面试的时候,到了类似的问题,吸取滴滴面试的教训,我们用一个子查询来解决这个问题: select name,sex,register,ordertime,orderuser from userinfo...这时候我们就会发现,运行面的代码,某些用户会返回两条数据,因为两个用户同一间接到了订单,对于其中一个用户来说,是当天的第一笔,对于另一个用户来说,不是当天的第一笔,这样就会出现问题了: ?...上面的代码中用到了mysql变量的知识,首先,我们大体讲一mysql中变量的相关知识。 mysql变量 mysql中变量不用事前申明,在用的时候直接用“@变量名”使用就可以了。...上面的效果得以实现,得益于mysql中变量select循环赋值的特性,即每取出一行,i的值都会变化一次,而在sql server中,i不会被循环赋值,所有列的值都是最后一次的i值。

2.8K31

翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 第 6 章:值的不可变性

重新赋值 进入下一个段落之前先思考一个问题 —— 你如何描述“常量”? … 你可能会脱口而出“一个不能改变的值就是常量”,“一个不能改变的变量”等等。...下面这行代码会抛出错误,这无可厚非: // 尝试改变 x,祝好运! x = 3; // 抛出错误! 但再次重申,我们并不是要改变这个数据,而是要对变量 x 进行重新赋值。...读者会在后面的代码里(再次错误地)认为 magicNums 的值仍然是 [1, 2, 3, 4]。因为他们猜测你之前使用 const 的目的就是“这个变量不会改变”。...如果你使用 const 声明变量来保存引用吗,这个变量的确没法重新赋值了,那么……然后呢? 从这方面来讲,认为 const 反而增加了函数式编程的困难度。的结论是:const 并不是那么有用。...因为值是可被携带的,但词法赋值并不是。你可以向函数中传入一个数组,这个数组可能会在你没意识到的情况改变。但是你的其他代码预期之外重新给变量赋值,这是不可能发生的。

1.2K50

你好,这30个Python常见错误都踩过吗!

也许你刚开始会忘掉这个,但是到了很快这就会成为一个下意识的习惯。 8)初始化变量 Python里,一个表达式中的名字它被赋值之前是没法使用的。...21)赋值语句不会创建对象的副本,仅仅创建引用 这是Python的一个核心理念,有时候当行为不对时会带来错误。在下面的例子中,一个列表对象赋给了名为L的变量,然后L又在列表M中被引用。...从技术上讲,Python是在编译def代码,去静态的识别本地变量,而不是在运行时碰到赋值的时候才识别到的。 如果不理解这点的话,会引起人们的误解。...当编译这则代码,Python碰到给X赋值的语句认为在这个函数中的任何地方X会被视作一个本地变量名。...但是之后当真正运行这个函数,执行print语句的时候,赋值语句还没有发生,这样Python便会报告一个“未定义变量名”的错误

57830
领券