zoukankan      html  css  js  c++  java
  • Python语言防坑小技巧

                    Python语言防坑小技巧

                                               作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

    一.赋值即定义

     1>.运行以下代码会出现报错

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 x = 100
     7 
     8 def outer():
     9     def inner():
    10         x += 100    #其实这里等效于"x = x + 100",我们直到这是一个赋值语句,会优先计算右边的等式,即"x + 100".而在此时由于x变量赋值即定义,即此时的x和全局作用域的x并非同一个对象。
    11         print(x)
    12     return inner
    13 
    14 foo = outer()
    15 
    16 foo()

    2>.使用global关键字解决以上报错

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 x = 100
     7 
     8 def outer():
     9     def inner():
    10         global x        #注意,我们先要在inner作用域中使用全局作用域的同名x变量就得优先使用"global"关键字进行声明。
    11         x += 100
    12         print(x)
    13     return inner
    14 
    15 foo = outer()
    16 
    17 foo()
    18 
    19 
    20 #以上代码输出结果如下:
    21 200

    3>.不推荐使用global

    global总结
      x+=1这种是特殊形式产生的错误的原因?先引用后赋值,而python动态语言是赋值才算定义,才能被引用。解决办法,在这条语句前增加x=0之类的赋值语句,或者使用global告诉内部作用域,去全局作用域查找变量定义
      内部作用域使用x = 5之类的赋值语句会重新定义局部作用域使用的变量x,但是,一旦这个作用域中使用global声明x为全局的,那么x=5相当于在为全局作用域的变量x赋值
    
    global使用原则
      外部作用域变量会内部作用域可见,但也不要在这个内部的局部作用域中直接使用,因为函数的目的就是为了封装,尽量与外界隔离
      如果函数需要使用外部全局变量,请使用函数的形参传参解决
      一句话:不用global。学习它就是为了深入理解变量作用域.

    二.列表中的"+"与"+="的区别

    1>.观察以下代码

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 def demo(x=[]):
     7     x += [1]                        #就地修改前一个列表,在其后追加后一个列表。就是extend方法。
     8     print(x)
     9 
    10 print(demo.__defaults__)            #我们可以查看默认参数列表
    11 
    12 demo()                                                      
    13 
    14  
    15 
    16 demo()
    17 
    18 print(demo.__defaults__)            #发现demo函数被调用2次后,默认参数的值也在跟随着变化!其原因是demo()执行完后弹栈会消亡,但解释器始终保留了一份"def demo(x=[])"的函数签名,这里面的x变量会随着解释器的消亡而消亡,除非我们使用"del"关键字去现实的删除该函数!如果我们这样干的话,后续就无法访问到该函数啦!
    19 
    20 
    21 #以上代码输出结果如下:
    22 ([],)
    23 [1]
    24 [1, 1]
    25 ([1, 1],)#!/usr/bin/env python
    26 #_*_conding:utf-8_*_
    27 #@author :yinzhengjie
    28 #blog:http://www.cnblogs.com/yinzhengjie
    29 
    30 def demo(x=[]):
    31     x += [1]                        #就地修改前一个列表,在其后追加后一个列表。就是extend方法。
    32     print(x)
    33 
    34 print(demo.__defaults__)            #我们可以查看默认参数列表
    35 
    36 demo()                                                      
    37 
    38  
    39 
    40 demo()
    41 
    42 print(demo.__defaults__)            #发现demo函数被调用2次后,默认参数的值也在跟随着变化!其原因是demo()执行完后弹栈会消亡,但解释器始终保留了一份"def demo(x=[])"的函数签名,这里面的x变量会随着解释器的消亡而消亡,除非我们使用"del"关键字去现实的删除该函数!如果我们这样干的话,后续就无法访问到该函数啦!
    43 
    44 
    45 #以上代码输出结果如下:
    46 ([],)
    47 [1]
    48 [1, 1]
    49 ([1, 1],)

    2>.列表防坑总结

    列表的"+""+="的区别:
        "+"表示两个列表合并并返回一个全新的列表。
        "+="表示,就地修改前一个列表,在其后追加一个列表。就是extend方法。

    3>.注意引用变量的是可以被就地修改的(以函数的默认值参数为例)

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 def demo2(x=1,y="abc",z={},*args,m=100,n,**kwargs):
     7     print(x,y,z)                            #打印位置参数
     8     print(m,n)                              #打印key-only关键词参数
     9     print(z.setdefault("abc","mn"))         #我们为"z"变量设置一组键值对
    10 
    11 
    12 
    13 print(demo2.__defaults__,demo2.__kwdefaults__)      #我们知道"__defaults__"保留的是位置参数相关信息,而"__kwdefaults__"保留的是关键字相关信息
    14 
    15 demo2(n=200)
    16 
    17 demo2(z = {},n = 200)
    18 
    19 print(demo2.__defaults__,demo2.__kwdefaults__)      #我们发现默认的"z"变量值是被咱们有意修改啦~
    20 
    21 
    22 
    23 
    24 #以上代码输出结果如下:
    25 (1, 'abc', {}) {'m': 100}
    26 1 abc {}
    27 100 200
    28 mn
    29 1 abc {}
    30 100 200
    31 mn
    32 (1, 'abc', {'abc': 'mn'}) {'m': 100}

    三.

  • 相关阅读:
    Java中的==和equals区别
    2014年06月30日
    20140625 20:39
    20140627 20:47
    2014年06月30日
    20140628 16:07
    hdu 1418 抱歉 (数学)
    hdu 1302 The Snail (模拟)
    hdu 1391Number Steps
    hdu 1395 2^x mod n = 1
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/11111684.html
Copyright © 2011-2022 走看看