学哥量化交易学习
持续学习,提高认知,磨炼技艺,从零基础学编程并跨过量化程序交易的大门。
 返回首页
 
 
0015b 编程入门python之函数补充说明
作者:学哥
发布时间:2017-3-1
第一部分讲完之后,有读者提出意见,说关于函数部分讲的太少,对于函数该如何设计和使用还缺少体会。
学哥也有体会,新手在如何定义函数和使用方面如果经验太少,即使掌握了基本语言,仍然会有无从下手的感觉。
因此,这里再补充一节课,详细说明一下,一般该如何定义函数和使用。

1.函数的定义
def function(params): block return expression/value 这个样式大家已经清楚,需要特别说明一下: (1)采用def定义函数,无需指明返回值的类型 (2)函数参数params可以是0个、1个或者多个,参数也无需指明类型 (3)return语句可写可不写,return后面不能再有代码,不写return则自动返回NONE 下面是一些例子:
2.函数的使用
先定义函数,再使用函数: python中不允许前向引用,也就是必须def函数在使用函数之前,如果反过来就会出错: 新建一个testadd.py文件,代码如下: print add(3,5) def add(x,y): return x+y 然后运行 testadd.py文件,会发现报错:name 'add' is not defined
3.参数传递
函数的参数类型,分为2大类:不可变类型和可变类型。 不可变类型:整数,字符串,元组,数值。 可变类型:列表,字典。 如果参数是可变类型,那么函数内部改变了该参数变量的值,则函数外部该变量的值同样被改变。 要根据实际情况来使用这种特征,有些情况如果不希望改变原来的参数值,那么可以在函数内部读取后赋值给一个新的变量; 这个前面有例子,这里只是补充说明一下。
4.常用系统内建函数
abs(x) 返回一个数字的绝对值。 cmp(x,y) 比较2哥对象大小,如果xy返回1,如果x==y返回0。 divmod(x,y) 除法运算,返回商和余数。 isinstance(object,class-or-type-or-tuple) 测试对象类型,返回bool。 len(object) 返回字符串或者序列的长度。 type(obj) 返回对象的数据类型。 min(x[,y,z...]) 返回给定参数的最小值,参数可以为序列。 max(x[,y,z...]) 返回给定参数的最大值,参数可以为序列。 还有其它的就不一一列出了,大家自行搜索,然后在python环境中进行测试验证具体的用法。
5.递归函数
在函数内部,可以调用其它函数。如果一个函数在内部调用自身本身,这个函数就是低轨函数。 来看一个例子,计算阶乘n!=1*2*3*...*n,用函数fact(n)表示,可以推理出: fact(n)=n!=1*2*3*...*(n-1)*n=(n-1)!*n=fact(n-1)*n 所以fact(n)可以使用n*fact(n-1),注意当n=1时需要特殊处理 于是,代码就是这样的: python是如何进行计算的呢,我们以fact(5)做为例子来单步跟踪看看。 fact(5)进入函数内部,不满足n==1的情况,执行下一句 return 5*fact(4),这时候,程序并不会返回,因为又碰到函数调用,python会将当前的5*保存到一个栈里面 然后去运行fact(4)函数 fact(4)进入函数内部,不满足n==1的情况,执行下一句 return 4*fact(3),这时候,程序并不会返回,因为又碰到函数调用,python会将当前的4*保存到一个栈里面 ,这时候栈里面有2个元素,最里面是5*,上面是4*,然后去运行fact(3)函数 fact(3)进入函数内部,不满足n==1的情况,执行下一句 return 3*fact(2),这时候,程序并不会返回,因为又碰到函数调用,python会将当前的3*保存到一个栈里面 ,这时候栈里面有3个元素,最里面是5*,上面是4*,上面是3*,然后去运行fact(2)函数 fact(2)进入函数内部,不满足n==1的情况,执行下一句 return 2*fact(1),这时候,程序并不会返回,因为又碰到函数调用,python会将当前的2*保存到一个栈里面 ,这时候栈里面有4个元素,最里面是5*,上面是4*,上面是3*,上面是2*,然后去运行fact(1)函数 fact(1)进入函数内部,满足n==1的情况,执行return 1语句 这时候,碰到return,则栈里面的最上面的2*会出栈,栈里面剩余5*4*3*总共3个,执行2*1,然后执行return 2 这时候,碰到return,则栈里面的最上面的3*会出栈,栈里面剩余5*4*总共2个,执行3*2,然后执行return 6 这时候,碰到return,则栈里面的最上面的4*会出栈,栈里面剩余5*总共1个,执行4*6,然后执行return 24 这时候,碰到return,则栈里面的最上面的5*会出栈,栈里面剩余0个,执行5*24,然后执行return 120 这时候,由于栈里面空了,就return数据返回。得到结果120。 递归函数的优点是定义简单逻辑清晰,但是需要注意防止栈溢出,也就是死循环调用。 假如上面的fact函数里面缺少if n==1这个代码就会导致死循环调用,这一定要避免。 再来看看,之前我们做过的斐波拉契数列,也可以改造为递归函数,会看起来更简洁: 相信大家在运行的时候会发现一个问题:运行速度比较慢。这是因为递归调用需要频繁的进栈出栈,消耗比较大。 可见,有时候,代码简洁并不一定是效率最高的方法,要根据实际情况灵活决定。
6.函数和模块设计定义的一些经验
一般而言,有这样一些约定俗成的经验: (1)将函数设计成简单的功能性单元,理想情况下,函数应简明扼要,若长度很大,可考虑分割成较短的几个方法。 (2)设计一个函数时,设身处地为使用这个函数的程序员考虑一下,使用方法应该是非常明确的。 (3)模块应尽可能短小精悍,而且只解决一个特定的问题,更有利于维护和灵活搭配组合使用。 (4)尽可能的“私有”。就是函数内部的变化对外部调用尽量减少干扰和改变,也就是不要修改或保存传入的数据。 (5)尽可能细致的加上注释,方便使用者和维护者。 (6)避免使用“魔术数字”,应创建常量,并使用有说明力的描述性名称,更易理解和维护。 (7)重要的参数在前,次要的参数在后且有默认值。 因为学哥也没有用python来做过真正的大项目,不过参照以前做java项目的经验来看,一个方法,只要发现有重复代码出现,就说明需要将这些重复代码独立出来做成函数,就是将代码不停的拆分拆分,直到感觉是在不能再拆了为止,如果调用的时候感觉有问题,再考虑合并或者调换等修改。总之,其中的一些感悟,只可意会,要靠大家在实际运用过程中不断分析总结。
学哥量化交易学习团队
   致力于:持续学习,提高认知,磨炼技艺,持续输出高质量的教程和课程,帮助更多的人从零基础学编程并跨过量化程序交易的大门。
零基础学编程Python入门课程
课程包含以下内容:
1.图文教程《零基础学编程入门-从Python到Web网站.pdf》,学哥原创版权,共计1024页高清图文教程。
2.视频课程《零基础学编程Python入门》,学哥原创版权,共计24节课45个高清视频。
3.视频教程《玩转魔方》,学哥原创版权,可以送给孩子,共计16个高清视频。
4.图文教程《如何寻找编程相关的电子书下载资源.pdf》。
5.加入学哥编程学习辅导QQ群在线交流。

客服 10:00-17:00
QQ: 44556287
微信公众号
学哥量化交易学习
 
  微信公众号:学哥量化交易学习     QQ群1:603559164    客服QQ号:44556287
工信部备案/许可证编号:沪ICP备15050545号-4