python函数

讲函数之前,先了解一下变量的作用域

变量作用域

2种变量作用域

  • 局部变量
  • 全局变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域,而局部变量只能在其被声明的函数内部访问,全局变量则可以在整个程序范围内访问

变量的作用域如下:

● L(Local):局部作用域
● E(Enclosing):闭包函数外的函数中
● G(Global):全局作用域
● B(Built-in):内建作用域

变量的属性与执行依据:

● 变量的先后顺序是:L –> E –> G –>B 的规则查找
● 在子程序中定义的变量称为局部变量
● 在程序的一开始定义的变量称为全局变量
● 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序
● 当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用,在其它地方全局变量起作用
● 当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了
● 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问

局部转全局: 将一个局部变量通过global关键字,转换为全局变量.

import os
import sys


def print_num():
    global num
    num = 1000
    print("函数内调用: ", num)

print_num()
print("函数外调用: ", num)

无参和有参函数

demo

#无参函数

def print_num():
    print("hello world!")

print_num()

#有参函数
def add(x,y):
    z=x+y
    print(z)

add(1,2)

函数参数的传递

Python中所支持的参数传递形式:

  • 普通参数:普通参数传递,在定义函数时就指定了规律是从左至右传递
  • 默认参数:定义函数时是使用"name=value"的语法直接给变量一个值,从而传入的值可以少于参数个数
  • 指定参数:调用函数时指定"name形式参数=value实际参数"的语法通过参数名进行匹配
  • 动态参数:在我们定义函数时,形式参数中收集任意多基于普通参数【定义函数时使用* :收集普通参数,返回元组,*args】【定义函数时使用**:收集指定参数,返回列表,**kwargs】
  • 动态参数解包:在调用函数时,使用**开头的参数,从而传递任意多基于普通或指定参数

demo

#普通传参
def stu(name,age,country):
    print("姓名:",name)
    print("年龄:",age)
    print("国际:",country)

stu("cc",18,"CN")

#带默认参数传递: 同样的,我们可以给指定的字段添加默认参数,如果用户不输入则默认使用指定参数
#这里需要注意的是:如果您要使用带默认参数的函数,则需要把带参数的字段,放在函数最后一项.
def stu2(age,country,name="aa"):
    print("姓名:",name)
    print("年龄:",age)
    print("国籍:",country)

stu2(23,"CN","aa")    #此时我们给予全部的参数则无默认值
stu2("cc",20,"AM")    #形参如何排列,实参就得如何排列  姓名: AM  年龄: cc  国籍: 20
stu2(18,"LOS")        #传递输入是忽略带有默认值的字段

#动态参数传递(传递列表): 若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数,传递一个列表.
def stu3(name,age,*args):
    print(name,age,args)

stu3("aa",22)
stu3("aa",22,"a","b","c")
ls=[1,2,3]
stu3("aa",22,ls)    #传入列表

#动态参数传递(万能参数): 我们使用*与**通常情况下可以传递任何值,所以称作万能参数.
def fun(*args,**kwargs):
    print(args,type(args))
    print(kwargs,type(kwargs))

ls2=[1,2,3,4,5]
dic={"a":1,"b":2,"c":3}
fun(*ls2,**dic)     #(1, 2, 3, 4, 5) <class 'tuple'>        {'a': 1, 'b': 2, 'c': 3} <class 'dict'>

函数的返回值

demo

#函数的返回值

def add(x,y):
    z=x+y
    print("函数内返回:",z)
    z+=10
    return z

z=add(1,2)
print("函数外返回:",z)

函数闭包:

闭包是由函数及其相关的引用环境组合而成的实体(闭包=函数+引用环境)这个从字面上很难理解。Python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).这个定义是相对直白的,好理解的,下面举一个简单的例子来说明.

def adds(x):
    def adder(y):return x+y
    return adder

c=adds(10)
print(type(c))
print(c.__name__)
print(c(10))

如上代码,在一个内部函数里:adder(y)就是这个内部函数,对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域adds里面,但不在全局作用域里,则这个内部函数adder就是一个闭包.闭包=函数块+定义函数时的环境,adder就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x.

函数嵌套与递归

除了函数的闭包以外,函数还支持两种调用方式,一种是嵌套函数,另一种是递归函数,这里需要注意的是,最好在开发中尽量少用这样的结构,这种结构一旦层数变多将很难后期进行维护,所以你懂的

demo:嵌套函数

import os

name = "cc"

def chage_name():
    name = "cc blog"

    def chage_name_new():
        name = "xiao blog"
        print("第3层循环打印: ", name)

    chage_name_new()  # 在函数内部调用内部的函数
    print("第2层循环打印: ", name)  # 第二层函数执行结果


chage_name()  # 调用最外层函数
print("查看最外层变量: ", name)  # 查看外层变量

运行结果:

第3层循环打印:  xiao blog
第2层循环打印:  cc blog
查看最外层变量:  cc

demo2:递归函数

import os
 
def fun(n):
    if 0==n:              # n=0 的话直接返回空,对用户输入的零进行判断
        return None
    elif 1==n:            # n=1 的话就不再递归
        return n
    else:
        return n*fun(n-1) # 递归在执行f(n-1),直到f(1)
 
print(fun(5))             # 120

'''
    f(5)的执行过程如下
        ===> f(5)
        ===> 5 * f(4)
        ===> 5 * (4 * f(3))
        ===> 5 * (4 * (3 * f(2)))
        ===> 5 * (4 * (3 * (2 * f(1))))
        ===> 5 * (4 * (3 * (2 * 1)))
        ===> 5 * (4 * (3 * 2))
        ===> 5 * (4 * 6)
        ===> 5 * 24
        ===> 120
'''

用递归实现二分法:

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 
def binary_search(dataset,find_num):
    print(dataset)
 
    if len(dataset) >1:
        mid = int(len(dataset)/2)
        if dataset[mid] == find_num:             #find it
            print("找到数字",dataset[mid])
        elif dataset[mid] > find_num :           # 找的数在mid左面
            print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)
        else:                                    # 找的数在mid右面
            print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
            return binary_search(dataset[mid+1:],find_num)
    else:
        if dataset[0] == find_num:               #find it
            print("找到数字啦",dataset[0])
        else:
            print("没的分了,要找的数字[%s]不在列表里" % find_num)
 
binary_search(data,66)

匿名函数

demo

#匿名函数的使用
# 定义匿名函数方式1(普通方式)
def func(arg):
    return arg + 1

result = func(123)
print(result)

# 定义匿名函数方式2(lambda表达式)
my_lambda = lambda arg: arg + 1
# 执行函数
result = my_lambda(123)
print(result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值