Python基础-函数

函数
定义

我们知道,程序是按顺序执行的,那么在开发中我们就会遇到一个代码罗列的问题,如果能按照我们意愿把一部分功能是实现的代码抽出来,在使用的时候就简单的一行或者几行就搞定?
因此函数便应运而生
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数的定义规则
  1. 以关键字def开头 然后跟着函数名,再次是小括号,
  2. 小括号内可以放入参数,也可以不放
  3. 函数内容必须以冒号起始,并且缩进
  4. 函数结束用return return后可以跟表达式,也可以不跟
  5. 在函数的第一行,可以根据需要选择性的写函数注释
def functionname( parameters ):
   "函数注释,可有可无"
   function_suite
   return [expression]
参数
必备参数

所谓必备参数是指,当定义的函数需要参数时,调用时必须要传入,否则报错
例如:

#定义函数
def printStr(str):
    'this is some discribe'
    print str
    return

#调用函数
'''如果这样调用 printStr(),那么会报错,必须这样调用 printStr('helle word')
这里的'hello word' 就是必备参数'''
关键字参数

听到这名字我们可能会感觉迷茫,那么先来个例子:

#可写函数说明
def printinfo( name, age ):
   print "aame: ", name;
   print "age ", age;
   return;
 #调用printinfo函数
printinfo( age=18, name="Rocky" );

例子中我们可以发现,调用函数的时候我们传入的参数和定义的参数顺序不一致,别担心这样也不会报错,因为 Python给我们处理了,最后得到结果仍然是正确的,原因是 传参时,是按着定义函数是预留的参数名(关键字)‘赋值’的,那么在使用参数的时候,也会根据变量名正确找到值

默认参数

默认参数 也叫缺省参数,在调用函数的时候,如果没有传入参数,那么函数机会使用默认的值运算


def printinfo( name, age = 18 ):
   print "aame: ", name;
   print "age ", age;
   return;
#调用printinfo函数
printinfo( name="Rocky" );

例如上例,按照正常的要求我们需要传入两个值,现在只传入一个值,而且运行通过!
仔细观察一下会发现这次定义的函数和原来的有所不同,这里的age直接赋值了,这样的形式定义的函数就是缺省参数函数,
特点:在不传入缺省参数的时候会默认使用预留参数值,传入的话没回覆盖,使用传入的值

不定长参数

不定长参数,顾名思义就是定义函数的时候参数预留参数预留个数不固定,理论上是想传入几个就传入几个,这里和java中的可变参数有异曲同工之妙
但是和java的方法定义不一致
不定长参数函数定义格式:

def functionname([formal_args,] *var_args_tuple ):
   function_suite
   return [expression]

说明:

  1. 这里的参数特点和以前的多了一个*
  2. 这里的*标注的变量名会存放所有未命名的变量参数

具体使用举例:

# 可写函数说明
def printinfo( arg1, *vartuple ):
   print arg1
   for var in vartuple:
      print var
   return;

# 调用printinfo 函数
printinfo( 10 );#结果是 10
printinfo( 70, 60, 50 ); #结果是 70,60,50
匿名函数

所谓匿名函数就是我们看不到函数的名字,他的创建需要通过lambda函数

lambda函数特点

  1. 它只是一个表达式
  2. 因为它主体就是一个表达式,所以创建匿名函数时候只能封装有限的逻辑
  3. 它有自己命名空间,不能访问自身参数之外的参数
  4. 它只有一行

格式:

lambda [arg1 [,arg2,.....argn]]:expression

匿名函数举例:

# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2;

# 调用sum函数
print "相加后的值为 : ", sum( 10, 20 ) #结果30
print "相加后的值为 : ", sum( 20, 20 ) #结果 40
关于变量的一些说明

变量,顾名思义是一个可变的量
例如 a = 1,a = ‘hello’ 等等 这里的a就是一个变量

变量的使用是有范围的,这个范围我们称之为作用域
根据作用域的不同,变量分为全局变量和局部变量

局部变量

在函数内部定义的变量它的作用范围只是在函数内部,属于局部范围,因此这样的变量为局部变量,一般情况下局部变量只能在函数内部访问使用,但是在局部变量定义的时候前面加入一个global就可以变成全局变量来使用了
例如:

Money = 2000
def AddMoney():
   global Money #表示是全局变量
   #以下语句会先使用Money 在方法内部有找不到因此会报错,虽然在全局中找到了Money,但是下语句是修改全局变量,除非用 global 修饰 否则一定报错
   Money = Money + 1
print Money
AddMoney()
print Money
这时候打印出来的结果是2001,
如果把  global Money注释掉 会报错:UnboundLocalError: local variable 'Money' referenced before assignment
这也就说明 函数外部的变量在内部如果不用global来标识一下直接使用会找不到局部变量
全局变量

和局部变量相反的,他的作用范围更广,全局定义 到处可用

深浅拷贝

拷贝,顾名思义,就是复制一个。在我们程序中有这样的一个场景:
我生命了一个变量b = 2,然后传入自定函数让b加1返回打印,结果函数内部打印是3,外部打印还是2

def addOne( b ):
    b = b+1
    print b
    return

b = 2
addOne(b) #结果为3
print b # 结果为2

这里我们就模糊了,在函数内部明明加一了 怎么最后没改变呢?

这里引入两个概念:可变对象与不可变对象

  1. 不可变对象
    在 python 中,strings, tuples, 和 numbers 是不可更改的对象,所谓的改变即使重新赋值,而重新赋值又是重新分配内存新建对象
  2. 可变对象
    在 python 中,list,dict 等则是可以修改的对象,注意,这里的修改修改的是元素,对象的内存地址没改变 可以使用 id(对象)前后查看

在上述例子中addOne的参数我们可以任意起名字,可以给他a等等
那么我们分析一下上述函数调用执行的过程

  1. 首先我们addOne(b)这是调用,b的值为2
    这个过程其实是把外部的变量的值2 赋值给我们形参b 这时候系统用重新创建了一个对象,这里我们虽然也叫b但是这个变量可以任意起名字
  2. 在函数内部我们做了变量加一,其实步骤是 b+1的值 有重新给了b 这时候的b又相当于新建的一个局部变量,
  3. 然后我们打印输出局部变量的值是3
  4. 打印全局变量b的值为2

在这里说明一下:新建对象就是重新分配一个内存地址,上例子中函数调用连续两次新建对象,这样和原来的b完全不是一回事,自然最后的值没有改变

浅拷贝

先看一个例子:

 a = [1, 2, 3]
 b = a
 b.append(5)
 print a, b 
结果是[1, 2, 3, 5] [1, 2, 3, 5]

这样我么们就发现问题了,说不对呀,我想在b的后面添加5,在怎么a也添加了呀
这就是浅拷贝,在这里,变量a和b都指向同一个对象(一个列表),所以,一旦你修改了二者之一,另外一个也会受到影响.无论怎样,都会修改原来的对象.
然后就有人问,我的需求即使要更改一个对象,另一个不变,这样我们就要引入深拷贝

深拷贝

再来看一个例子:

import copy #这里是模块的使用,下节在讲述
a = [ ['a'], [1, 2], ['rocky', 21] ] #原始数据
copy_a = copy.deepcopy(a) #复制数据,注意是深拷贝
copy_a[1].append(3) #复制后的数据修改
print a, copy_a  #打印

结果:[['a'], [1, 2], ['rocky', 21]] [['a'], [1, 2, 3], ['rocky', 21]]

最后发现 原始数据a没有改变,改变的是复制后的数据,目的达到,至于原理需要看底层代码,这里不再讲述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值