1.代码在执行的过程中,遇到函数定义,初始化函数生成存储函数名,默认参数初识值,函数地址的函数对象。

2.代码执行不在初始化函数,而是直接执行函数体。

代码实例

这要从函数的特性说起,在 Python 中,函数是第一类对象(function is the first class object),换而言之,函数也是对象,跟整数、字符串一样可以赋值给变量、当做参数传递、还可以作为返回值。函数也有自己的属性,比如函数的名字、函数的默认参数列表。

# 函数的名字

>>> func.__name__

  'func'

  # 函数的默认参数列表

>>> func.__defaults__

  ([ 1, 1, 1, 1, 1], 1)

def是一条可执行语句,Python 解释器执行 def 语句时,就会在内存中就创建了一个函数对象(此时,函数里面的代码逻辑并不会执行,因为还没调用嘛),在全局命名空间,有一个函数名(变量叫 func)会指向该函数对象,记住,至始至终,不管该函数调用多少次,函数对象只有一个,就是function object,不会因为调用多次而出现多个函数对象。

函数对象生成之后,它的属性:名字和默认参数列表都将初始化完成。

初始化完成时,属性 __default__ 中的第一个默认参数 numbers 指向一个空列表。

当函数第一次被调用时,就是第一次执行 func()时,开始执行函数里面的逻辑代码(此时函数不再需要初始化了),代码逻辑就是往numbers中添加一个值为1的元素

第二次调用 func(),继续往numbers中添加一个元素

第三次、四次依此类推。

所以现在你应该明白为什么调用同一个函数,返回值确每次都不一样了吧。因为他们共享的是同一个列表(numbers)对象,只是每调用一次就往该列表中增加了一个元素

如果我们显示地指定 numbers 参数,结果截然不同。

>>> func(numbers=[ 10, 11])

[ 10, 11, 1]

因为numbers被重新赋值了,它不再指向原来初始化时的那个列表了,而是指向了我们传递过去的那个新列表对象,因此返回值变成了 [10, 11, 1]

那么我们应该如何避免前面那种情况发生呢?就是不要用可变对象作为参数的默认值。

正确方式:

>>> deffunc(numbers=None, num=1):

... ifnumbers isNone:

... numbers = [num]

... else:

... numbers.append(num)

... returnnumbers

...

 

python函数默认参数为可变对象的理解的更多相关文章

  1. 【转】Python函数默认参数陷阱

    [转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...

  2. Python面试题目之Python函数默认参数陷阱

    请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...

  3. [python]函数默认参数顺序问题

    python 函数参数定义有四类: 1.必选参数:调用函数时候必须赋值的参数. a,须以正确的顺序传入函数b,调用时的数量必须和声明时的一样 def exa(x): return x #b作为参数进入 ...

  4. 使用可变对象作为python函数默认参数引发的问题

    写python的都知道,python函数或者方法可以使用默认参数,比如 1 def foo(arg=None): 2 print(arg) 3 4 foo() 5 6 foo("hello ...

  5. python函数默认参数陷阱

    对于学习python的人都有这样的困惑 def foo(a=[]): a.append(5) return a Python新手希望这个函数总是返回一个只包含一个元素的列表:[5].结果却非常不同,而 ...

  6. python函数默认参数作用域

    当def函数参数默认值为对象时,例如列表[],字典{} 示例1:猜测一下,会输出什么??? def ddd(a,b=[]): b.append(a) return b print(ddd(1)) pr ...

  7. Python 函数(默认参数)

    默认参数 设置默认参数时,有两点需要注意:一是必选参数在前,默认参数在后,否则python的解释器会报错二是当函数有多个参数时,把变化大的参数放前面,变化小的放后面,变化小的参数就可以作为默认参数 d ...

  8. Python函数默认参数的陷阱

    默认参数实际上只有一个值 代码1 def func(l = 1): l += 1 print(l) func() func() func() 代码2 lst = [] def func(a,l = l ...

  9. python函数默认参数坑

    def add(a=3,b): print a,b add(4) 这样写的话,运行的话就会报错:SyntaxError: non-default argument follows default ar ...

随机推荐

  1. ubuntu 16.04 修正网卡与ifname对应关系

    一台工控机,含有6个网口,但是名称  enp3s0 等等与网口顺序对应不起来. 现在修改脚本 /etc/udev/rules.d/70-persistent-net.rules ,如果文件不存在,可以 ...

  2. Python-爬虫-租房Ziroom

    目标站点需求分析 涉及的库 import requestsimport timeimport pymongofrom lxml import etreefrom requests.exceptions ...

  3. HTML_1

    HTML 指的是超文本标记语言: HyperText Markup LanguageHTML 不是一种编程语言,而是一种标记语言标记语言是一套标记标签 (markup tag)HTML 使用标记标签来 ...

  4. nginx 配置白名单

    在http 模块 增加 geo $remote_addr $ip_whitelist{ default 0; include white_ip.conf; } 在location 模块 增加 (注意i ...

  5. log4j 知识点

    什么是log4j? log4j 是一个帮助程序员将日志语句输出到各种输出目标的工具. log4j 包的设计使得日志语句可以保留在已发布的代码中,而不会产生高性能成本. log4j 使用分层记录器可以有 ...

  6. Confluence 6 识别慢性能的宏

    Page Profiling 给你了有关页面在载入的时候操作缓慢的邪教,你可以将下面的内容添加到调试(debug)级别: Version 3.1 及其后续版本 设置包名字为 com.atlassian ...

  7. 实用的sublime插件集合 – sublime推荐必备插件

    Package Control 功能:安装包管理 简介:sublime插件控制台,提供添加.删除.禁用.查找插件等功能 使用:https://sublime.wbond.net/installatio ...

  8. SpringBoot集成Shiro

    Shiro是一个安全框架,控制登陆,角色权限管理(身份认证.授权.回话管理.加密) Shiro不会去维护用户,维护权限:这些需要通过realm让开发人员自己注入 1.在pom.xml中引入shiro的 ...

  9. 《剑指offer》重建二叉树

    本题来自<剑指offer> 重构二叉树 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2 ...

  10. hdu1811 拓扑排序+并查集缩点

    /*给定两个点之间的三种关系 = < >如果是=就将两点放到同一个集合里进行缩点 离线处理所有关系,先用并查集将等于关系缩成一个点 */ #include<bits/stdc++.h ...