Python 基础 (函数)

函数
函数是可以重复使用的程序片段,函数让你命名一块语句代码,允许你使用这个具体的函数名,在程序的任何地方,任何次数的运行那段代码。这被称作调用函数。我们已经多次使用过像 len 和 range这样的内置函数了。

函数概念可能是任一重要软件的最重要的基础材料(在任何一门编程语言),所以我们将在这一节探讨函数的各个方面。

函数用def 关键字定义,def关键字后面跟着函数的标识符名字(函数名),然后是一对括号,括号内可以包含一些变量,然后是冒号结束这一行。下一行就是代码块的开始,是函数的一部分。下面的例子显示,实际上挺简单的。

Def sayHello():
print(‘hello world’)
然后调用
sayHello()
sayHello()
调用多少次都行。

代码运行原理
我们定义了一个函数叫做sayHello,使用上面解释的语法。这个函数没有parameters (一般翻译成形式参数),所以没有在括号内声明变量。Parameters 对于函数,就像是函数的一个输入。所以,可以直接传递给函数各种不同的值。然后得到(函数返回)的相应的值。
看到了吗?我们可以两次调用同样的函数,这意味着没有必要写两次同样的代码。

函数形式参数(parameters)
一个函数可以接收参数,也就是我们提供给函数的值,函数用这些值做些事情。这些参数就像变量,除非这些变量的值在我们调用(就是使用函数)函数时,已经被定义。并且在函数运行时已经被赋值。
在定义函数时括号内被指定的参数,用逗号隔开,(叫做parameters,中文翻译为形式参数),当我们调用函数时,我们以同样方式提供值。请注意,这个术语,函数定义时的参数名字叫做形式参数,而我们提供给函数参数值时,参数叫做实际参数(auguments)。(译者又及—英文容易区别和理解,因为单词十分不同,但中文容易混淆,请留意。要理解区分这两个术语,因为后面会频繁使用。不能像某些视频上那样说的,这种区分无所谓。因为理清思路需要这些术语。有英语基础的直接记忆英文词最佳)
例子:
Def printMax (a, b):
If a > b:
Print (a, ‘ is maximum’)
elif a == b:
print (a, ‘ is equal to’, b)
else:
print (b, ‘ is maximum’)

下面直接传值

printMax(3,5)

下面传递变量作为实际参数
x= 5
y= 7
printMax ( x, y)

代码运行原理
我们定义了一个函数叫做 printMax 用了两个形式参数,分别是 a 和 b; 我们用一个简单的 if … else 语句, 发现更大的数字,然后打印出较大的那个数字。

第一次调用函数时,我们直接提供数字作为实际参数(以后简称实参,形式参数简称形参),第二个例子,我们用变量作为实际参数调用函数。这样的话,就是将实际参数(x)的值赋值给了(绑定)形式参数a 。而实际参数(y)的值赋值(绑定)给了形式参数b。printMax函数在两个例子中运作方式是一样的。

局部变量
当你定义函数时,在其内部声明变量的时候,它们与函数外部使用的同名变量没有一毛钱关系。也就是说,对函数来说,变量名字就是local的,这就叫做变量的scope(作用域)。从变量定义名字的点开始,变量的作用域就开始了,一直到它声明变量所在的那块语句块结束而结束。不好理解的话,看例子:
X = 50
Def func(x):
print(‘x is’, x)
x = 2
print(‘changed local x to’, x)
func(x)
print(‘x is still’, x)

代码运行原理
在函数体内部第一行,我们第一次打印名字为x 的值,Python使用的是在主体语句块(函数定义的上面)声明形式参数的值。接下来,我们将2赋值给x ,x 是局部变量,当我们变动函数体内部的x时, 在函数外面的主体代码里的x值是不受影响的。
最后的这个print语句,展示了x在主体语句块中的值,所以,前面调用的这个函数,证实了它(外面的x)实际上是不受函数内部的局部变量赋值所影响的。

全局变量语句
如果你要把一个值赋值给一个程序中最顶端的一个名字,(比如,没有在任何像函数和类内部的作用域中),你需要告诉Python,名称是不是局部的,是全局的。 我们使用 global 语句做这事。不可能在函数外部,不使用global 语句来定义一个变量(译者表示怀疑,还是能不使用global就不使用它吧。)
(还有一段没有翻译,译者感觉翻译了就有点乱了)
其实是在函数内用global,来定义全局变量。(译者澄清)例子:

非常遗憾,图片无法上传,请移步到CSDN博客(Mark学编程)或者微信公众号(Mark学编程)或者QQ加群(Mark学编程)参考。没有办法,只能这样给人一广告之嫌了。

作者说了好多global,感觉作者有点混。不过,你要简化的话,把这个例子看懂了,就行了。例子中,函数内用global声明了x全局变量。所以,当在函数内部重新赋值给x时,这个变化就已经影响到了函数外部主体块中x的值。(据说,大牛们对global的使用有着较大的分歧,所以,能避免就避免吧。毕竟我们不是大牛—译者注)

默认实参值
有些函数,你可能需要让一些形式参数成为可选,此时这些可选的参数要使用默认值,以防止用户不提供这些参数值。我们使用默认实参值搞定此事。(也就是)在函数定义时,用赋值运算符(=)后面紧跟着默认值,附在形式参数名后面,从而将默认实际参数值指定给了形式参数。
请注意,默认实际参数值应该是常数,更准确的说,默认实参值应当是不可变的,这会在今后章节中详细讲解。现在,只要记住就好。
例子:
Def say(message, times=1):
Print(message * times)
say(‘hello’)
say(‘world’, 5)

代码运行原理
叫say名字的函数用于打印字符串,根据指定次数决定打印次数。如果我们不提供值,那么,依据默认,字符串只打印一次。我们通过指定一个默认实参值 1 给形式参数 times 来达成这个目的。
在say 的第一次调用时,我们仅仅提供了字符串,所以它只打印了字符串一次。在第二次调用时,我们提供了两者–字符串和实际参数5,指出我们要“say”这个字符串信息5遍。

小心:
只有在形式参数列表的结尾部分,形式参数才能给予默认实际参数值。你不能在一个没有默认值的形参前面,放置一个有默认值的形参。这是因为值赋值给形参是依据位置的。例如: def func(a, b=5) 是有效的,但是 def func(a=5, b) 是无效的。

关键字实参
如果你有些函数有许多形式参数,你需要特别指定一些参数,那么你可以给予形式参数赋值并命名形式参数,这叫做关键字实参。我们使用名字(关键字)而不是用位置(我们一直这么做)来具体的指定函数的实际参数。
这样做有两个好处,其一,使用函数更容易,因为我们无需担忧实际参数的次序。其二,我们只赋值我们想要赋值的形参的,假设其他形参有实参默认的值。
举例:
def func(a, b=5, c=10):
print(‘a is’, a, ‘and b is’, b, ‘and c is’, c)
func(3, 7)
func(25, c=24)
func(c=50, a=100)
输出:
a is 3 and b is 7 and c is 10
a is 25 and b is 5 and
c is 24 a is 100 and b is 5 and c is 50

代码运行原理
叫做func的函数有一个形式参数,其没有默认参数值,后面的两个形式参数有默认值。
第一个用法,func(3,7), 形式参数a 得到3这个值,b 是 7;c 得到默认值10;
第二个用法,func(25, c=24), a 得到25的值,因为位置,c是24,因为是关键字实参,变量 b 得到默认的值5;
第三个用法,func(c=50, a=100), 我们使用关键字实参为所有指定参数赋值。请注意,次序已经无足轻重。
(不知道你掌握了吗?,在调用函数时,参数列出的使用列出的实参,没有的使用默认实参值。明确列出有关键字的用关键字实参,没有关键字的按照位置实参—应该是这么理解比较全面吧—译者加注,anyway, 需要大量练习才行)

VarArgs 形参
有时候,我们定义的函数需要使用不定数量的形参,也就是说,实参的数量是变化的,可以使用星号达成这个目的。
例子:

非常遗憾,图片无法上传,请移步到CSDN博客(Mark学编程)或者微信公众号(Mark学编程)或者QQ加群(Mark学编程)参考。没有办法,只能这样给人一广告之嫌了。

代码运行原理
当我们声明一个带星号的形式参数,比如 param, 然后所有的位置实参,从这一点开始一直到结束,都被收集到一个叫做param的元组中。
同样的,当我们声明一个带双星号的形参时,比如
param,我们把从这一点开始到结尾的关键字参数收集起来,作为一个字典称作*param。
我们会在今后章节探讨元组和字典

return语句
此语句用于函数返回。比如打断函数,我们也可以选择性使用return从函数返回一个值。
例子:
Def maximum(x, y):
If x > y:
return x
elif x == y:
return (‘the number are equal’)
else:
return y
print(maximum(2,5))

代码运行原理
此函数返回形参中最大的,在这个例子中,就是我们提供给函数的数字。它使用了一个简单的if…else语句发现更大的值然后返回那个值。
请注意,一个return语句没有值的话相当于return None. None 是Python的一个特别类型,代表空。比如,如果你有个None值,那就被用于表示那个变量没有值。
每个函数都暗含一个return None 语句,除非你已经写了自己的return语句。你可以通过运行print(someFunction())来体会这一点(你可以print(someFunction())。此函数没有使用return语句,如下:
def someFunction():
pass
Python中的pass语句用于表示空语句块。

文档字符串
Python有一个极好的特征叫做文档字符串。通常用它的更短的名字来引用(DocStrings),这是个重要的工具供你使用。这将帮助你写出更好的程序的文档,使程序更容易理解。令人惊奇的是,我们甚至可以在程序实际运行时,得到文档,比如说从一个函数里。见图例子:

非常遗憾,图片无法上传,请移步到CSDN博客(Mark学编程)或者微信公众号(Mark学编程)或者QQ加群(Mark学编程)参考。没有办法,只能这样给人一广告之嫌了。

代码运行原理:
函数第一逻辑行的字符串是这个函数的文档字符串。请注意,文档字符串同样应用于模块(modules)和 类(classes),这些我们将在相应章节学习。

习惯上,文档字符串是个多行的字符串,第一行开始一个大写字母,然后结束用英语句号。然后第二行空行,然后第三行开始详细的解释(遗憾的是,我上面的图没有遵守,不换图了,引以为戒—译者注)。强烈推荐你在重要的函数中遵守这些传统规矩。
你可以使用doc(英文状态下的双下划线),这个函数的属性来访问printMax的文档字符串。(作者在此提到,Python视一切为对象,函数自然不例外。所以这里可以使用.点来(使用)函数对象的属性,这些以后会学习)
如果你在Python内使用过help(),那么你已经看到了文档字符串的使用方法。它只不过就是使用函数的doc属性,并用整洁的方法展示出来。你可以用help(printMax)来试验,看看返回什么。如果是在交互编辑器,一般的按下‘q’键就退出了help界面。
(还有一点关于docString,略去不翻译了。有兴趣的参见英文原版。)

总结
我们已经学习了很多函数的方面,但是并没有涵盖函数的所有方面。当然,我们已经覆盖了绝大多数日常使用有关函数的使用方法。
下一章节,我们将学习如何使用和创建Python模块。

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

推荐阅读更多精彩内容