函数基础

函数的概要

一、1、减少代码重复,2、方便修改,更易扩展,3、保持代码一致性

创建函数的规则:

   1、函数代码块以 def 关键词开头,后接函数名称和圆括号

   2、任何传入参数和变量放在圆括号

   3、以冒号结束

      4、代码块需缩进4个空格

函数的创建:

def 函数名(传参列表):#define的缩写def作为函数的关键字,定义的意思
    函数体

def f():
    print("ok")

f() #调用函数,调用是后面一定要跟括号
输出结果:
ok

#光写一个f是一个变量名字,这是存的一条条的执行语句,之前变量存的是一个固定对象
print f  #内存地址存的是 print("ok")
输出结果:
<function print_info at 0x027575F0>

 

传入一个参数
def f(index):
    print("funciton %s"%index)

f(1) #1传给了index
输出结果:
function 1
f(2) #1传给了index
输出结果:
function 2

 

传入两个参数
def add(a,b):#a,b是形参,不传值不占内存
    print (a+b)

add(3,4)#调用函数并传入两个参数(按顺序对应) ,a接收3,b接收7
输出结果:
7

形参多少个,实参我们就要传入多少个
add(3)#报错,需要传2个参数,你只传了1个
add(3,4,5)#报错,需要2个参数,你传入了3个

 

def print_info(name,age):
    print("name: %s"%name)
    print("age: %s"%age)

必须参数,以正确的顺序传入函数,调用时的数量必须和声明的一样

print_info("xiaohu",38)#调用函数,并传入2参数
输出结果:
name: xiaohu
age: 38

"""
%s 可以接受int ,%d 不能接受string型
"""
print_info(38,"xiaohu") #不能这样传,因为38是年龄,必需参数

 

关键字参数

def print_info(name,age):
    print("name: %s"%name)
    print("age:   %d"%age)
    
print_info(age = 39,name = "xiaohu")#有定义关键字,就没有顺序关系了    

 

默认参数
def prnit_info(name,age,sex):
    print("Name: %s"%name)
    print("Age: %d"%age)
    print("Sex: %s"sex)

pirnt_info("xiaohu",40,"male")
print_info("jinxin",41,"male")
print_info("wuchao",12,"male")

#普遍是男性时,可以把sex默认为male
#默认参数的放后边,默认参数在形参里面去加
def prnit_info(name,age,sex = "male"):
    print("Name: %s"%name)
    print("Age: %d"%age)
    print("Sex: %s"sex)

#男性的时候就属于默认的,女性时给传female
pirnt_info("xiaohu",40)
print_info("jinxin",41)
print_info("wuchao",12)
print_info("lichun",18,"female")

 

不定长参数

def add(x,y,z):
    print(x+y+z)

add(1,2,3)

以上这个加法器太low了,只能三位相加,如果有更多位怎么办?

def add(*args):#参数前面一定要带个*号,代码的是现在接收的是一个不定长参数
    print(args)#打印一个元组
add(1,2,3,4,5)#传一个元组
输出结果:
(1,2,3,4,5)

多位数的加法器
def add(*args):
    sums = 0
    for i in args:
            sums += i
    print (sums)
add(1,2,3,4,5)#函数调用
输出结果:
14

 

 接收不定长的有命名的参数
def print_info(name,age,sex,job):#这是一个定长的参数
    print("name: %s"name)
    print("age: %d"%age)
    print("sex: %s")
    print("job: %s"%job)
    
print_info("alex",18,"male",job="TT")#函数调用,
传入两种参数,一种没有名字,一种有名字

以下这种方式去接收参数,就没有接不到的,无名的*args接收,有名的**kwargs接收
例:
def print_info(*args,**kwargs): #这是不定长无命名参数和不定长无命名参数
    print(args)#接受的是无名字的值,一个元组形式
    print(kwargs)#接收的是一个有名字的,键值对的,以一个字典形式
    for i in kargs:
        print ("%S:%S"%(i,kwargs[i]))

print_info("alex",18,"male",job="TT",hobby="girls")#函数调用
输出结果:
("alex",18,"male")
{"job":"TT","hobby":"girls"}  

关于顺序:
def func(name,age="22",*args,*kwagrs)
def func(关键字参数,默认参数,不定长无命名参数(元组),不定长有命名参数(字典))

 

需要打开文件,写入内容,关闭文件,重复多次操作

f = open("log.txt" , "a")
f.write("2018-1-26 21:15  function1")
f.close()

f = open("log.txt" , "a")
f.write("2018-1-26 21:15  function2")
f.close()
楼上代码重复太多,减少代码的重复,可以使用函数

def logger():
    f = open("log.txt","a")
    f.write(2018-1-26 21:15 function1)
    f.close()

logger()#调用函数
楼上代码虽然使用函数减少了代码量,但是每次写入的内容都是一样的
我们需要每次写入不一样的内容,如何解决?
实例:

def logger(log_text):#给函数设置形参,调用的时候传入值
    f = open("log.txt","a")
    f.write(log_text)
    f.close()

logger("2018-1-29 21:30,function1")#调用函数,并传入实参,每次调用可以传入不样的值
logger("2018-1-29 21:30,function2")#调用函数,并传入实参

  

def action1(n): #功能1
    print ("starting action1……)
    with open("日志记录","a") as f:
        f.write("end action %s \n"%n)

def action2(n):#功能2
    print(starting action2……)
    with open("日志记录""a") as f:
        f.wirte("end action %s \n"%s)

重复代码,打开日志记录,写入日志,我们需要把这一部份提出来写成一个函数
日志记录,最重要的是时间我们要加个时间进去,把记录时间加在logger函数内。
这就保持扩展性(在一个函数内扩展),和一致性(格式一致)
import time
def logger(n):
    time_format = "%Y-%m-%d %H:%M:%S" #时间的格式
    time_current = time.strftime(time_format)#当前时间
    with open("日志记录""a") as f:
        f.write("%s end action %s \n"%(time_current,n))

def action1(n): #函数里面调用函数
    print("starting action1……")
    logger(n)

def action2(n):
    print ("starting action2……")
    logger(n)

 return 

return的作用

def f():
    print("ok")
    return 1  #作用 1、结束函数,2、返回某个对象           
    print ("ok1")#这句没任何意思了,因为前面就结束了

返回什么内容,给谁呢?
a = f()
print (a)
输出结果:
1
-------------------------------------------------------
def f():
    print ("ok") #没有return返回值,自动返回一个None(系统默认)

d = f()
print (d)
输出结果:
None
------------------------------------------------------
例:
def add(*args):
    sums = 0
    for i in args:
        sums += i
    return sums #不加返回值,就会默认返回None
dd = add(1,3,5,7,9)
print dd
输出结果:
25
----------------------------------------------------
def foo():
    return 1,"123",8 #return多个对象

print (foo())
输出结果:
(1,"123",8)# 返回的是一个元组

注意:
 要想获取函数执行的结果,就用return语句把结果返回
1、函数如果没有return 会默认返回一个None
2、如果retrun 多个对象,python会帮我们把多个对象封装成一个元组返回
3、函数执行过程中遇到return,就会停止执行,并返回结果。return就代表着函数结束    

函数的作用域

函数的作用域

def f():函数有自己的作用域
    a = 10 #仅在函数里面有作用,出了这个函数就没有了
print (a)
报错提示a没有被定义
--------------------------------------------
最外层built_in ,里面一层global,再往里一层enclosing ,最里面一层local
顺序从里到外 (global ,nonlocal 都是为了改外部变量进行一个修改用的)
x = int(2.85) #系统固定模块里面的变量。
g_count = 0#全局作用域
def outer():
    o_outer = 1 #嵌套作用域
    def inner(0:
        i_count = 2#局部作用域
        print(i_count)

outer()
-----------------------------------------------------
count = 10
 def outer():
     print (count)
     count = 5 #全局变量在局变量变是不可以修改的,你只可以看
     print (count)
 outer()
输出结果:
报错,不能修改全局变量
---------------------------------------------------
count = 10
 def outer():
     #print count 注释掉这一行
     count = 5 #这样就可以,相当于重新定义了一个count
     print (count)
 outer()#调用函数
输出结果:
10
------------------------------------------------
想要在局部变量修改全局变量,加一个global 
count = 10
def outer():
    global count #声明是全局变量
    print (count)
    count = 1
    print (count)

outer()#调用函数
输出结果:
10
1
-------------------------------------------------
局部修改嵌套变量(第二层),python3新加的功能nonlocal
def outer():
    count = 5
    def inner():
        nonlocal count
        print (count)
        count = 10
        print (count)
    inner()
    print (count)
outer()

 递归函数

什么是递归函数?

1、可以调用函数本身

2、有一个结束条件

3、递归能做的事情循环都可以解决

例一、

不使用递归,1+2+3+...100=?

i = 1
sums = 0
for i in range(100):
     sums = sums +i
print sums       

输出结果:
5050
使用递归函数
def
sum(n): if n == 1: return 1 return n+sum(n-1) print sum(100) 输出结果: 5050

例二、

不用递归
def
fib(max): n,b,a = 0,0,1 while n<max: print b b,a = a,a+b n +=1 fib(8) 输出结果: 0 0 1 1 2 3 8 13 21
用递归
#斐波那契规则0,1,1,2,3,5,8,13,21
def fib(n):    #
    if n == 1 or n == 0:
        return n 
    return fib(n-1) + fib(n-2)#减的是下标的位置
print fib(6)#下标为6的数是8,8前面一位是5,8前面两位是3。所以是5+3=8
print fib(4)#下标为4的数是3,3前面一位是2,8前面两位是1,所以是2+1=3
输出结果:
8
3
list = []#把获取的斐波拉契数字存放到列表中 for i in range(0,20):   list.append(fib(i)) print list
输出结果
[0, 1, 1, 2, 3, 5, 8, 13, 21]

def fibs(n):
list = []
  for i in range(n+1):
    list.append(fib(i))
  return list

print fibs(10)

输出结果:

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 

 

posted @ 2018-01-26 21:28  藤上小冬瓜  阅读(138)  评论(0编辑  收藏  举报