第七课 定义函数

函数很重要 函数很重要 函数很重要

看了这个前提就知道这节课有多关键,开始。

  • 定义函数

for example
输出斐波那契序列

def feibo(n):
    '''输出斐波那契数列

    输出n个数
    '''
    a,b = 0, 1
    list = []
    while len(list) < n:
        a,b = b, a+b
        list.append(b)
    print(*list)
feibo(10)
输出结果:
1 2 3 5 8 13 21 34 55 89

第一行:def,命名规范,参数,格式
关键字 def 引入了一个函数 定义。在其后必须跟有函数名和包括形式参数的圆括号。函数体语句从下一行开始,必须是缩进的。注意':'
这里我命名为 feibo,参数为 n 。
第二行:文档字符串
第一行应该是关于对象用途的简介。简短起见,不用明确的陈述对象名或类型,因为它们可以从别的途径了解到(除非这个名字碰巧就是描述这个函数操作的动词)。这一行应该以大写字母开头,以句号结尾。

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it. 
          No, really, it doesn't do anything.

函数 调用 会为函数局部变量生成一个新的符号表。确切的说,所有函数中的变量赋值都是将值存储在局部符号表。
变量引用首先在局部符号表中查找,然后是包含函数的局部符号表,然后是全局符号表,最后是内置名字表。因此,全局变量不能在函数中直接赋值(除非用 [global]语句命名),尽管他们可以被引用。
函数引用的实际参数在函数调用时引入局部符号表,因此,实参总是 传值调用 (这里的 总是一个对象 引用 ,而不是该对象的值)。 一个函数被另一个函数调用时,一个新的局部符号表在调用过程中被创建。
一个函数定义会在当前符号表内引入函数名。函数名指代的值(即函数体)有一个被 Python 解释器认定为 用户自定义函数 的类型。 这个值可以赋予其他的名字(即变量名),然后它也可以被当做函数使用。这可以作为通用的重命名机制。

f = feibo
f(20)
输出结果:
1 2 3 5 8 13 21 34 55 89
1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
>>> 

没有 return 语句的函数确实会返回一个值,虽然是一个相当令人厌烦的值(指 None )。这个值被称为 None(这是一个内建名称)。如果 None 值是唯一被书写的值,那么在写的时候通常会被解释器忽略(即不输出任何内容)。

  • 默认参数值

最常用的一种形式是为一个或多个参数指定默认值。
默认值在函数 定义 作用域被解析

i = 5
def f(x = i):
    print(x)
i = 6
f()
输出结果:
5
=====
i = 5
def f(x = i):
    #加了一行代码
    x = i
    print(x)
i = 6
f()
输出结果:
6

默认值只被赋值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。例如,下面的函数在后续调用过程中会累积(前面)传给它的参数:

def f(a, L=[]): 
      L.append(a) 
      return L
print(f(1))
print(f(2))
print(f(3))
输出结果:
[1]
[1, 2]
[1, 2, 3]
  • 关键字参数值

在函数调用中,关键字的参数必须跟随在位置参数的后面。传递的所有关键字参数必须与函数接受的某个参数相匹配 (例如 actor不是 parrot函数的有效参数),它们的顺序并不重要。这也包括非可选参数(例如 parrot(voltage=1000)也是有效的)。任何参数都不可以多次赋值。
主要看有没有默认值,没有默认值的参数是不是被赋值了

dic = {'shi':'a','hu':'b','li':'c','liu':'d'}
def ranking(name: str = 's',age: str = 'A'):
    print('%s的age是%s'%(name,age))
    return
for i,j in enumerate(dic):
    ranking(j,dic[j])

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。

def person(name, age, **kw): 
      print('name:', name, 'age:', age, 'other:', kw)
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
  • 可变参数列表

一个最不常用的选择是可以让函数调用可变个数的参数。这些参数被包装进一个元组。在这些可变个数的参数之前,可以有零到多个普通的参数。
通常,这些可变参数是参数列表中的最后一个,因为它们将把所有的剩余输入参数传递给函数。任何出现在 *args后的参数是关键字参数,这意味着,他们只能被用作关键字,而不是位置参数。

  • 参数列表的分拆

另有一种相反的情况: 当你要传递的参数已经是一个列表,但要调用的函数却接受分开一个个的参数值。这时候你要把已有的列表拆开来。
你可以在调用函数时加一个 * 操作符来自动把参数列表拆开。

>>> print(list)
(1, 3, 4, 5, 6)
>>> print(*list)
1 3 4 5 6
>>> print(range(1,5))
range(1, 5)
>>> print(*range(1,5))
1 2 3 4

用 ** 操作符分拆关键字参数为字典。

  • 函数注解

函数注解是关于用户自定义的函数的完全可选的、随意的元数据信息。
注解是以字典形式存储在函数的 annotations 属性中,对函数的其它部分没有任何影响。
参数注解(Parameter annotations)是定义在参数名称的冒号后面,紧随着一个用来表示注解的值得表达式。返回注释(Return annotations)是定义在一个 -> 后面,紧随着一个表达式,在冒号与 -> 之间。

def introDog(name: str = 'dog',age: int = 2, size: '大小' = 'big') -> list:
    print(name,age,size)
    return [str,age,size]
introDog('小白',22,'small')
print(introDog.__annotations__)
输出结果:
小白 22 small
{'size': '大小', 'name': <class 'str'>, 'age': <class 'int'>, 'return': <class 'list'>}
  • 遗留问题

1.作用域问题
2.函数的参数
3.编码风格

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容