八. Python基础(8)--函数

1 ● 函数返回布尔值

注意, 自定义的函数也可以是用来作逻辑判断的, 例如内置的startswith()等函数.

def check_len(x):

    '''

 

    :param x:

    :return:

    '''

    if len(x) > 5:

        return True

    # 如果这里不写else, 并return一个False, 那么返回一个None, 相当于False.

 

2 ● 为函数添加说明文档

print(check_len.__doc__)

'''

结果:

    :param x: *******

    :return: *******

'''

 

3 ● 有关函数的执行步骤

程序从上到下执行到一个函数定义的语句时, 内存中只是保存了函数名, 并没有执行函数体内的语句

 

3 ● 函数的作用

① 减少代码的冗余

② 提高代码的可读性

③ 提高代码的重用性

④ 提高代码的的可扩展性

⑤ 解耦

 

4 ● 解耦(decoupling)

面向过程的编程--功能与功能之间耦合很紧密

解耦--把一个功能尽量细化成多个小功能, 并且功能与功能之间的影响尽量减到最小--不宜把一个很复杂的功能放在一个函数里

程序要做到: "高内聚, 低耦合"high cohesion and low coupling

 

5 ● Python3允许使用汉语作为函数名

def 函数名(参数1, 参数2): # 形参

    '''

    这是一个解决什么问题的函数

    :param
参数1:

    :param
参数2:

    :return:

    '''

    print('函数体')

    返回值 = [参数1, 参数2]

    return 返回值

 

接受返回值 = 函数名('刘桂香', 88) # 实参

print(接受返回值)

函数体

['刘桂香', 88]

 

6 ● 默认参数

① 可以不给它传值的形参

② 如果不给它传值, 那么实参接收默认值,如果给它传了值, 就接收传入的值

③ 默认的值是在定义阶段就已经确定了

a = 18

def age(a1, a2 = a):

    print(a1, a2)

a = 20

 

age(10) # 10 18

 

7 ● 默认参数的陷阱: 针对可变的数据类型

def demo3(a = []):

    a.append(1)

    print(a)

#

# demo3()

# demo3() # 仍用默认的列表

# demo3() # 仍用默认的列表

# '''

# [1]

# [1, 1]

# [1, 1, 1]

 

# '''

# demo3([]) # 用新列表

# demo3([]) # 用新列表

# demo3([]) # 用新列表

'''

[1]

[1]

[1]

'''

 

# demo3()

# demo3([]) # 用新列表, 而不是默认的列表

# demo3() # 用默认的列表

'''

[1]

[1]

[1, 1]

'''

# 还有一种解决方法是在进入函数体的时候置空默认的列表

def demo3(a = []):

    a = []

    a.append(1)

    print(a)

#

# demo3()

# demo3() # 仍用默认的列表

# demo3() # 仍用默认的列表

'''

[1]

[1]

[1]

'''

 

8 ● 动态参数(dynamic argument)/变长参数(variable length argument)

We can collect the arguments using the * and ** specifiers in the function's parameter list; this gives you the (unnamed) positional arguments as a tuple and the (named) keyword arguments as a dictionary.

在形式参数前面添加标识符"*", 表示我们可以将任意数量的、无名的(unnamed)位置实参以元组的形式传递给形参.

在形式参数前面添加标识符"**", 表示我么可以将任意数量的、有名的(named)关键字实参以字典的形式传递给形参.

 

9 ● 动态参数*args

#① 站在函数定义的角度: *做组合(gather)用, 将多个参数组合成一个元组

#② 站在函数调用的角度: *做打撒(unpack)用(打散列表, 元组, 字符串), 将一个列表或者元组打散成多个参数

#③ * 只针对按位置传参

def my_sum(*args): # 实参会组合成一个元组

    count_sum = 0

    for i in args:

        count_sum += i

    return count_sum

 

print(my_sum(1,2,3)) # 将1,2,3 组合成一个元组, 结果: 6

li = [1,2,3]

print(my_sum(*li)) # 先将列表li打散成1,2,3, 再将1,2,3组合成后元组, 结果: 6

 

10 ● 动态参数**kwargs

#① 站在函数定义的角度: *做组合(gather)用

#② 站在函数调用的角度: *做打撒(unpack)用(打散列表或者元组)

#③ ** 只针对按关键字传参

def demo4(**kwargs):

    print(kwargs)

 

demo4(a = 1, b = 2, c = 3) # 关键字a,b,c不用加引号, 结果的键有引号: {'a': 1, 'b': 2, 'c': 3}

dic = {'a': 1, 'b': 2, 'c': 3}

demo4(**dic) # 先将词典dic打散, 然后组合为一个词典,结果和dic一模一样: {'a': 1, 'b': 2, 'c': 3}

 

11 ● 动态函数*args和**kwargs的混用

def demo5(*args, **kwargs):

    print(args)

    prind = {'a':11, 'b':22, 'c':33}

 

t = (1,2,3)

d = {'a':11, 'b':22, 'c':33}

 

print(*t) # 1 2 3

demo5(*t)

'''

(1, 2, 3)

{}

'''

print(*d) # a b c, 不能用**d

demo5(**d)

'''

()

{'a': 11, 'b': 22, 'c': 33}

'''

 

12 ● 参数划分的总结:

# 站在传参(实参给形参传递参数)的角度or站在函数调用的角度: 所有的参数都是实际参数

①按位置传值

②按关键字传值

 

# 站在形参接受实参传递的值的角度or站在函数定义的角度:所有的参数都是形式参数

①位置参数

②默认参数

③动态参数: *args, ** kwargs

※定义顺序:位置参数, 动态参数 * args, 默认参数, 动态参数 ** kwargs

 

13 ● 作为形参的位置参数, 动态参数*args, 默认参数, 动态参数**kwargs的定义顺序

def func(位置参数1, 位置参数2, *args, 默认参数 = 10, **kwargs):

    print(位置参数1, 位置参数2)

    print(默认参数)

    print(args)

    print(kwargs)

 

# func(1,2,3,4,5,默认参数= 'hahaha', a =10, b =20)

'''

1 2

hahaha

(3, 4, 5)

{'a': 10, 'b': 20}

'''

# func(1,2,3,4,5,a=10, b=20)

'''

1 2

10

(3, 4, 5)

{'a': 10, 'b': 20}

'''

 

14 ● 区分关键字参数和默认参数

① 关键字参数是针对实参而言的, 准确来说, 它是按照关键字传值的实参

② 默认函数是针对形参而言的

# 有关键字参数

def foo(bar, baz):

    pass

 

foo(1, 2) # 按照位置(position)传值的实参

foo(baz=2, bar=1) # 按照关键字(keyword)传值的实参

# 有关默认参数

def foo(baz, bar =5): # 默认形参前可以有位置形参

    print(baz, bar)

 

foo(1, 2) # 1 2

foo(1) # 1 5

 

 

# 下面的代码报错(non-default argument follows default argument)

def foo(bar =5, baz): # 默认参数后不允许有位置参数

    print(baz, bar)

 

foo(1, 2)

# 详见下面代码, 注意区分关键字参数和默认参数

def fun1(x=5, **kwargs):

    print(x)

    print(kwargs)

 

#① fun1(a=1, b=2)

'''

5

{'a': 1, 'b': 2}

 

fun1(a=1, b=2)

'''

 

#② fun1(x=7, a=1, b=2)

'''

7

{'a': 1, 'b': 2}

'''

#③ fun1(7, a=1, b=2)

'''

7

{'a': 1, 'b': 2}

'''

 

# ④ fun1(7, x=1, b=2)

'''

fun1() got multiple values for argument 'x'

'''

 

# ⑤

'''

def fun1(x=5, *args):

    print(x)

    print(args)

 

fun1(1,3,6)

'''

 

# 注意: 这里虽然没有报错, 但是作为默认参数的x就没有意义了, 因为此时没有办法在不给x传值的情况下还能打印出默认的5

 

# ⑥

'''

def fun1(*args, x=5):

    print(x)

    print(args)

 

fun1(1,3,6)

'''

# 注意: 这里的x不是关键字参数, 而是默认参数

'''

5

(1, 3, 6)

'''

 

15 ● 函数的嵌套

def func():

    print(123)

    def func2():

        print(345)

 

    if __name__ == '__main__':

        func2() # 如果注释掉此行, 那么func2不会运行

 

func()

 

16 ● 函数嵌套的应用场景

# 例如: 生成验证码

# 画线

# 打点

# 生成图片

 

def 生成验证码():

    def 画线():

        pass

    def 打点():

        pass

    def 生成图片():

        pass

    画线()

    打点()

    生成图片()

函数嵌套使用的目的: 为了保证某些功能特有的函数不被其他人随意地调用

 

17 ● 如何给内嵌的函数传实参?

# 方法1:

def func(x, y, z):

    print(x, y, z)

    def func_inner(a,b,c):

        print('func_inner', a, b, c)

    func_inner(x, y, z)

 

func(4,5,6)

'''

4 5 6

func_inner 4 5 6

'''

# 方法2(升级版, 使用动态参数)

def func(*args, **kwargs):

    print(args)

    print(kwargs)

    def func_inner(a,b,c):

        print('func_inner', a,b,c)

    func_inner(*args, **kwargs)

 

func(1,2, 3)

'''

(1, 2, 3)

{}

func_inner 1 2 3

'''

func(1, b = 2, c = 3)

'''

(1,)

{'b': 2, 'c': 3}

func_inner 1 2 3

'''

 

知识补充:

1● 有关函数的return

def fun():

    return 123 # Python中, 一遇到return就会停止操作, 不会再执行

    return 456 # 不会被执行

 

def fun():

    return (123, 456) # 返回一个元组, 可以返回其它任何数据类型

# python返回值的种类:

# ① 返回None--a, 如果函数里什么都不写; b, return; c,return None

# ② 返回一个值,

# ③ 多返回值, 以元组的形式

return 111, {123, 456}

# 返回一个元组(111, {123, 456})

# 相当于: return(111, {123, 456})

# return的作用;

# ① 返回值

# ② 结束函数

 

2 ● 接收返回值

# ① 一个对象接受一个值

# ② 多个对象接受多个值, 个数要相等(拆包/解包(pack)的问题)

 

3 ● 实参 & 形参

# 站在函数定义的角度上, 所有的参数都叫形式参数, 简称形参

# 站在函数调用的角度上, 所有的参数都叫实际参数, 简称实参

The names given in the function definition are called parameters whereas the values you supply in the function call are called arguments.

在函数定义时赋予的名称(names)叫作形参, 在函数调用时提供的值(values)叫作实参

# Parameter: Functions are declared with 0 or more "formal parameters", which are unbound local variables. When the function is called, the argument

# Argument: An expression passed to a function when it is called.

函数的本质: an object resulting from evaluation of a def block or a lambda expression.

八. Python基础(8)--函数的更多相关文章

  1. 十八. Python基础(18)常用模块

    十八. Python基础(18)常用模块 1 ● 常用模块及其用途 collections模块: 一些扩展的数据类型→Counter, deque, defaultdict, namedtuple, ...

  2. python基础之函数详解

    Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...

  3. python基础——匿名函数

    python基础——匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便.  在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时 ...

  4. python基础——返回函数

    python基础——返回函数 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回.  我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_ ...

  5. python基础——sorted()函数

    python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个d ...

  6. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  7. python基础——匿名函数及递归函数

    python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x ...

  8. Python学习笔记(一)python基础与函数

    1.python基础 1.1输入与输出 输出 用print加上字符串,就可以打印指定的文字或数字 >>> print 'hello, world' hello, world > ...

  9. Day3 - Python基础3 函数、递归、内置函数

    Python之路,Day3 - Python基础3   本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8. ...

随机推荐

  1. 【debug、info、warn、error】四者之间的区别与用法

    debug:需要在调试过程中输出的信息,但发布后是不需要的(当然发布后,也是看不到的) info:需要持续输出的信息(无论调试还是发布状态) warn:警告级别的信息(不严重) error:错误信息( ...

  2. LeetCode--350--两个数组的交集2

    问题描述: 给定两个数组,编写一个函数来计算它们的交集. 示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2,2] 示例 2: 输入: nums1 = ...

  3. 20181011xlVba提取邮箱手机号码

    Sub TransferData() AppSettings Dim StartTime As Variant Dim UsedTime As Variant StartTime = VBA.Time ...

  4. yii框架中获取添加数据后的id值

    Yii::$app->db->createCommand()->insert('month4_user',['openid'=>$openid,'integ'=>0])- ...

  5. 4、Ubuntu系统环境变量详解

    参考:Linux公社Ubuntu系统环境变量详解 UNIX/Linux系统中的环境变量和库文件的使用方法 由于Linux系统严格的权限管理,造成Ubuntu系统有多个环境变量配置文件,因此我们需要了解 ...

  6. selenium chrome 自动加载flash

    #coding:utf-8from selenium import webdriverfrom selenium.webdriver.support.select import Selectfrom ...

  7. org.json.JSONException: JSONObject["shophours"] not found.

    没有这个元素造成的.问题代码: value = jsonObject.get(entry).toString(); 分析原因: json中没有这个key,更没有这个key所对应的值 解决办法:判断一下 ...

  8. Oracle 基本操作--数据类型、修改和删除表、增删改查和复制表

    一.Oracle基础数据类型:数据类型: 创建数据表时,设计数据表的结构问题,也就是设计及确定数据表中各个列的数据类型,是数值.字符.日期还是图像等其他类型. 因为只有设计好数据表结构,系统才会在磁盘 ...

  9. python 小练习3

    求大蜜题:给你两个正整数a(0 < a < 100000)和n(0 <= n <=100000000000),计算(a^n) % 20132013并输出结果 ret = 1 d ...

  10. 2017-5-19&5-23/系统性能指标

    1. 系统性能指标包括哪些? 业务指标.资源指标.中间件指标.数据库指标.前端指标.稳定性指标.批量处理指标.可扩展性指标.可靠性指标. 1)业务指标:主要包括并发用户数.响应时间.处理能力. 指标 ...