美文网首页
python(一)谈一下几个常见的坑

python(一)谈一下几个常见的坑

作者: 王大吉 | 来源:发表于2018-11-07 23:03 被阅读0次

    零:

    先看几个代码

    >>> a=10000
    >>> b=10000
    >>> a is b
    False
    >>> c=a
    >>> c is a
    True
    >>> id(a)
    140620919220456
    >>> id(b)
    140620919220432
    >>> id(c)
    140620919220456
    

    这里的a和b,虽然都是同样的值1000 但他们并不是同一个东西,所以a is b 是 False。从代码层面讲,这里是因为 在定义a=10000的时候,计算机在140620919220456的地方开辟了一段内存,存为值10000,然后再给这段内存值 取了个名字叫a 。 定义b=10000的时候 计算机又在140620919220432的地方存了一个10000 取名字叫b 这俩货都不在同一个地方,只是凑巧值一样罢了,所以 a is b当然False 了 当执行 c = a 的时候,计算机只是给给140620919220456这段内存取了个别名,叫c而已。别忘了这段内存以前还有个名字叫a。既然是同一个东西 只是名字不同 那 c is a 当然True了
    所以这里的 a b c与其叫变量名称 不如叫指针更合适 比如a指向的地址为内存140620919220456的值。

    一:

    看一个常见的错误例题

    def fun(a=[]):
      a.append(1)
      print(a)
    

    调用这个函数两次 我们会看到

    >>> fun()
    [1]
    >>> fun()
    [1, 1]
    

    如果把参数a的默认参数换为字典呢?

    def fun(a={}):
      import random
      key = random.randint(1, 100)
      a[key] = 1
      print(a)
    
    >>> fun()
    {46: 1}
    >>> fun()
    {74: 1, 46: 1}
    >>> 
    

    怎么从原理来解释这件事情呢?当函数初始化的时候 并不是分配了一个空的list 或者空的dict给函数 而是给a的一个list或者dict的地址。在运行的时候,直接在这个地址指向的地方,开始操作。我们把参数的ID打出来看一看

    >>> def fun(a=[]):
    ...   a.append(1)
    ...   print(a)
    ...   print(id(a))
    ... 
    >>> fun()
    [1]
    4501980800
    >>> fun()
    [1, 1]
    4501980800
    >>> 
    

    我们可以看到 id并没有变 如果你学过C语言那么你应该一下就明白这里是指针的意思。
    所以我们一定要理解到,这里参数传进去的,只是一个指针,只是一个地址,并不是一个实实在在的数据结构段。

    二:

    函数都有返回值,比如return 0 return "ok"等 如果一个函数没有刻意的写明return 那么默认return None 这个在初学python的时候就讲过,那么除了 int str 等类型,还有哪些可以作为return的值呢?函数可以不可以呢?

    # 定义一个函数 不管接受到什么参数 直接返回接受到的东西
    def return_fun(a):
      return a
    >>> return_fun(1)
    1
    >>> return_fun('aaaa')
    'aaaa'
    >>> 
    # 再定义一个加法函数
    def add(a, b):
      return a + b
    >>> add(1,2)
    3
    # 执行下面的代码
    >>> new = return_fun(add)
    >>> new
    <function add at 0x10b9351b8>
    >>> add
    <function add at 0x10b9351b8>
    >>> new(1,2)
    3
    

    看到没 new 和 add 是完全一样的东西,也就是说 return_fun 接受了一个add 函数 然后又返回了这个函数 然后把这个函数赋值给了new 也就是说 现在new 这个变量 和add指向的是同一块代码区域 都是0x10b9351b8
    想一下 为什么能return 一个函数呢? 其实啊 return "aaaa" 并不是return了字符串”aaaa“本身, 而是return的一个地址 那个地址里存的是一窜"aaaa"字符串而已。弄懂了这个,也就不难理解为什么能return一个函数,因为其实return的并不是函数本身,而是return一个指向那段函数代码的一个指针而已,上面代码中,new就是那个指针,new后面加个括号new(1, 2) 就是执行new指向的代码段。

    相关文章

      网友评论

          本文标题:python(一)谈一下几个常见的坑

          本文链接:https://www.haomeiwen.com/subject/dkfwzftx.html