函数具有独立性。也就是常说的不要有太强的耦合性。要让函数能够独立于外部的东西。参数和return语句就是实现这种独立性的最好方法。

尽量不要使用全局变量,这也是让函数具有低耦合度的方法。全局变量虽然进行了函数内外通信,但是它强化了函数对外部的依赖,常常让函数的修改和程序调试比较麻烦。

如果参数的对象是可变类型的数据,在函数中,不要做对它的修改操作。当然,更多时候,参数传入的最好是不可变的。

函数实现的功能和目标要单一化。每个函数的开头,都要有简短的一句话来说明本函数的功能和目标。

函数不要太大,能小则小,根据前一条的原则,功能目标单一,则代码条数就小了。如果感觉有点大,看看能不能拆解开,分别为几个函数。

不要修改另外一个模块文件中的变量。这跟前面的道理是一样的,目的是降低耦合性。

递归

列举一个简单的例子。

>>> def newsum(lst):

... if not lst:

... return 0

... else:

... return lst[0] + newsum(lst[1:])

...

>>> newsum([1,2,3])

6

这是一个对list进行求和的函数,当然,我没有判断传给函数的参数是否为完全由数字组成的list,所以,如果输入的list中字母,就会编程这样了:

>>> newsum([1,2,3,'q'])

Traceback (most recent call last):

File "", line 1, in

File "", line 5, in newsum

File "", line 5, in newsum

File "", line 5, in newsum

File "", line 5, in newsum

TypeError: cannot concatenate 'str' and 'int' objects

这就是本函数的缺憾了。但是,为了说明递归,我们就顾不了这么多了。暂且忽略这个缺憾。注意上面的函数中,有一句:return lst(0)+newsum(lst[1:]),在这句话中,又调用了一边函数本身。对了,这就递归,在函数中调用本函数自己。当然,区别在于传入的参数有变化了。为了清除函数的调用流程,我们可以将每次传入的参数打印出来:

>>> def newsum(lst):

... print lst

... if not lst:

... return 0

... else:

... return lst[0] + newsum(lst[1:])

...

>>> newsum([1,2,3])

[1, 2, 3]

[2, 3]

[3]

[]

6

这就是递归了。

其实,即使不用sum,也可以用for来事项上述操作。

>>> lst = [1,2,3]

>>> sum_result = 0

>>> for x in lst: sum_result += x

...

>>> sum_result

6

铭记:函数是对象

还记得,在第一部分学习的时候,不断强调的:变量无类型,数据有类型,那时候遇到的数据包括字符串、数值、列表、元组、字典、文件,这些东西,都被视为对象。函数跟它们类似,也是对象。因此就可以像以前的对象一样进行赋值、传递给其它函数、嵌入到数据结构、从一个函数返回给另一个函数等等面向对象的操作。当然,函数这个对象也有特殊性,就是它可以由一个函数表达式后面的括号中的列表参数调用。

>>> def newsum(lst): #依然以这个递归的函数为例

... print lst

... if not lst:

... return 0

... else:

... return lst[0] + newsum(lst[1:])

...

>>> lst = [1,2,3]

>>> newsum(lst) #这是前面已经常用的方法

[1, 2, 3]

[2, 3]

[3]

[]

6

>>> recusion_fun = newsum #通过赋值语句,让变量recusion_fun也引用了函数newsum(lst)对象

>>> recusion_fun(lst) #从而变量能够实现等同函数调用的操作

[1, 2, 3]

[2, 3]

[3]

[]

6

再看一个例子,在这个例子中,一定要谨记函数是对象。在list中,可以容纳任何对象,那么,是否能够容纳一个函数中呢?

>>> fun_list = [(newsum,[1,2,3]),(newsum,[1,2,3,4,5])]

>>> for fun,arg in fun_list:

... fun(arg)

...

[1, 2, 3]

[2, 3]

[3]

[]

6

[1, 2, 3, 4, 5]`

[2, 3, 4, 5]

[3, 4, 5]

[4, 5]

[5]

[]

15

函数,真的就是对象啊。

既然是对象,就可以用dir(object)方式查看有关信息喽:

>>> dir(newsum)

['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

>>> dir(newsum.__code__)

['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']

>>> newsum.__code__.__doc__

'code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\nCreate a code object. Not for the faint of heart.'

>>> newsum.__code__.co_varnames

('lst',)

>>> newsum.__code__.co_argcount

1

所以,在使用函数的时候,首先要把它放在对象的层面考量,它不是什么特殊的东西,尽管我们使用了不少篇幅讲述它,但它终归还是一个对象。

python函数编写_python 函数编写条规-阿里云开发者社区相关推荐

  1. python链表划分_《Python自然语言处理》——1.2 近观Python:将文本当做词链表-阿里云开发者社区...

    本节书摘来自异步社区<Python自然语言处理>一书中的第1章,第1.2节,作者[美]Steven Bird,Ewan Klein,Edward Loper, 陈涛,张旭,崔杨,刘海平 译 ...

  2. mysql数据库div函数_关于使用mysql中的div函数报错?报错-问答-阿里云开发者社区-阿里云...

    数据库MySQL 5.5.27 jar包:mysql-connector-java-5.1.21.jar mybatis-spring-1.1.1.jar druid-0.2.10.jar 集成myb ...

  3. python网络模块_Python的pyroute2网络模块-阿里云开发者社区

    Pyroute2是纯python的netlink库,只需要python标准库不需要其他第三方的库. 最常用的是监控事件,例如监控磁盘空间事件: from pyroute2 import DQuotSo ...

  4. python正则匹配中文_python 正则表达式匹配中文-阿里云开发者社区

    python 正则表达式匹配中文 文件编码为 utf-8 设置默认编码为 utf-8 中文需要转换为 \u 形式的编码,也就是  编码, 轮换方法,cmd 下执行 python 进入 python 命 ...

  5. python数据科学实践指南_《Python数据科学实践指南》——导读-阿里云开发者社区...

    前 言 为什么要写这本书 我接触大数据技术的时间算是比较早的,四五年前当大数据这个词火遍互联网的时候,我就已经在实验室里学习编程及算法的知识.那个时候我一心想要做学术,每天阅读大量的英文文献,主要兴趣 ...

  6. python多线程原理_代码详解Python多线程、多进程、协程-阿里云开发者社区

    云栖号资讯:[点击查看更多行业资讯] 在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 一.前言 很多时候我们写了一个爬虫,实现了需求后会发现了很多值得改进的地方,其中很重要的一点就是爬 ...

  7. python es 数据库 复合查询bool_es 入门-阿里云开发者社区

    **注意事项-------使用ealsticsearch要配置java的开发环境JDK(1.8以上) ealsticsearch:               索引(Index)    类型(type ...

  8. python和pythonamd64_python amd64什么意思-问答-阿里云开发者社区-阿里云

    AMD64,或"x64",是一种64位元的电脑处理器架构.它是基于现有32位元的x86架构,由AMD公司所开发,应用AMD64指令集的自家产品有Athlon(速龙) 64.Athl ...

  9. pg数据库生成随机时间_postgresql 时区与时间函数-阿里云开发者社区

    postgresql 时区与时间函数 rudygao 2016-02-03 1951浏览量 简介: --把时间戳转成epoch值 postgres=# select extract(epoch fro ...

最新文章

  1. 「留光」1小时:中科大让我们离「量子U盘」又近了一步
  2. 用一句SQL取出第 m 条到第 n 条记录的方法
  3. 使用github时因fatal: remote origin already exists错误,无法提交
  4. GitHub 发布 2018 年开源项目趋势预测
  5. windows下客户端连接上马上会断开连接_Fix SSH客户端登录会话超时设置
  6. SQL Server商业智能中ODS表和Dim表必须有的字段
  7. 想成长为一名年薪50万+的实战型架构师?必掌握这7大实战技能经验
  8. CVPR 2021|人脸属性风格解耦
  9. 从嵌入式系统到无线模组 周立功单片机欲站在物联网的风口
  10. mysql身份证校验码_javascript身份证验证代码
  11. 一个java程序员自学IOS开发之路(五)
  12. Cisco:DHCP自动获取IP地址
  13. 处理器后面的字母含义_和机农一起探寻辅音字母f的含义
  14. JavaSE详细总结——万字纯手码
  15. 帧间的SAD和SATD
  16. Virtualbox源码分析4:VMM虚拟化实现源码分析1
  17. java的round函数加点差_【JAVA】Math.Round()函数常见问题“四舍5入”
  18. 乱世奸雄纵横三国:品曹操
  19. 单片机烧录不进去怎么办?通用类!
  20. Mybatis(尚硅谷)

热门文章

  1. canvas绘图粒子扩散效果【原创】
  2. MingW环境下的windows编程
  3. ASP.NET MVC实践系列11-FCKEditor和CKEditor的使用
  4. layui中接收modelView中返回的对象并赋值给容器
  5. 快速读取内存文件-内存映射文件的方法
  6. [ CodeForces 1063 B ] Labyrinth
  7. 代理模式(Proxy)--静态代理
  8. 【JQuery】数据
  9. python 的列表遍历删除
  10. 事件处理介绍(简要学习笔记十七)