Python学习之路怎么学习 函数

1. 定义函数

1.1 一般函数

函数是带名字的代码块,该代码块是完成特定工作的固定代码序列。如果程序中多次出现相同或相似的代码块,则应将这段代码提取出来,编写成函数,然后多次调用。通过编写函数可以避免重复工作,使程序的编写、阅读、测试和修复更容易。请使用描述性的函数名来命名函数,以大致表明函数的功能,这样即使没有注释也能容易理解。函数名应尽量只有小写字母和下划线。以下是两个最基本的函数,有参数与无参函数:

在调用函数前,必须先定义函数!即函数的定义部分必须在调用语句之前。

上述代码中的三引号字符串叫做文档字符串,他们既可以被用作代码注释,也可用于自动生成有关程序中函数的文档。

实参和形参

这两个概念经常被搞混,函数定义中的参数叫做形参,比如上述函数greet_user2(username)中的username就是形参;传递给函数的参数叫做实参,比如在调用greet_user2(“jesse”)时的“jesse”就是实参。

1.2 空函数

如果想定义一个什么都不做的函数,可以使用pass语句。

如果为了让程序能跑起来,但暂时又不写这个函数,可以使用pass语句。这里pass用作占位符。

2. 传递参数

2.1 位置参数(必选参数)

这就是要求实参的顺序和形参的顺序相同。

对于位置参数,应该注意实参的传递顺序,如果顺序不对,结果会出乎意料:有可能报错,如果不报错,函数所要表达的意思可能改变。

2.2 关键字参数(传实参时)

如果函数的形参过多,则很难记住每个位置的参数是用来干什么的,如果用键值对的方式传递实参,这个问题就能迎刃而解,这就是关键字参数。在传递参数时,直接将形参与实参关联,这样就不用在意实参的位置,依然以上述代码为例,函数定义不变:

请注意,这是一种传递参数的方法!在调用函数时使用!

2.3 默认参数(定义函数时,形参)

编写函数时可以为每个形参指定默认值,给形参指定了默认值之后,在调用函数时可以省略相应的实参。使用默认值可以简化函数调用,也可清楚地指出函数的典型用法。比如上述describe_pet()函数如果给形参animal_type指定默认值"dog",则可以看出这个函数主要是用来描述狗这种宠物的。

在函数调用时,如果给形参提供了实参,Python将使用指定的实参;否则将使用形参的默认值。

注意:默认参数是在函数定义时使用!在定义函数时带有默认值的形参必须在没有默认值的形参后面!

还有一点值得注意:默认参数必须指向不变对象!请看以下代码:

如果你在学习Python的过程中遇见了很多疑问和难题,可以加-q-u-n   227 -435-450里面有软件视频资料免费

当给这个函数传递了参数时,结果是正确的,而且,在没有传递参数且第一次调用时,返回结果也是正确的,然而,没有传递参数且第二次、第三次调用时,结果则成了问题。这是因为,Python在函数定义的时候,默认参数的值就被计算了出来,形参只要不指向新的值,它就会一直指向这个默认值,但如果这个默认值是个可变对象,就会出现上述情况。

要修正上述例子,可以使用None, str之类的不变对象。如下:

补充–设计不变对象的原因:

①对象一旦创建则不可修改,可以减少因修改数据而产生的错误;

②由于对象不可修改,在多任务环境下不需要加锁,同时读不会出错。所以,我们在设计一个对象时,能设计成不变对象则设计成不变对象。

3. 返回值

3.1 返回简单值

函数并非总是直接显示输出,它可以处理一些数据并返回一个或一组值。在Python的函数中,使用return语句来返回值。以下是一个参数可选的带有返回值的函数例子:

3.2 返回字典

Python函数可以返回任何类型的值,包括列表和字典等复杂的数据结构。

3.3 返回多个值

return语句后面用逗号分隔多个值,则可返回多个值:

但其实这是个假象,其实函数返回的是一个元组(Tuple),只是最后对元组进行了解包,然后对a,b进行了平行赋值。

如果函数返回多个值,但有些值并不想要,则这些位置的值可以用单下划线进行接收:

4. 传递列表

将列表传递给函数,函数可以直接访问其内容或对其进行修改。用函数处理列表可以提高效率。

以下代码是一个打印程序,将未打印的设计在打印后转移到另一个列表中,此代码中未使用函数:

现在用两个函数来重组这些代码:

从以上代码可以看出,使用了函数后,主程序变为了短短四行。

相比于没有使用函数的代码,使用了函数后代码更易读也更容易维护。

在编写函数时,尽量每个函数只负责一项功能,如果一个函数负责的功能太多,应将其分成多个函数。同时,函数里面还能调用另一个函数;函数里也能再定义函数!

禁止函数修改列表:

有时候需要禁止函数修改列表,以上述代码为例,print_models()函数在执行完成后清空了未打印列表unprinted_design,但有时我们并不希望这个列表被清空,而是留作备案。为解决此问题,可以向函数传递副本而不是原件,如下:

如果从C/C++的角度来看(没有研究过Python底层代码,这里仅是猜测),实参unprinted_designs是一个指针,当他传递给函数时,形参得到了这个变量的一个拷贝,形参也指向了内存中的那片区域,所以能直接修改。而当使用切片传递拷贝时,Python先在内存中复制一遍实参unprinted_designs指向的数据,并给这片数据的地址赋给一个临时的变量,然后再将这个临时变量传递给形参。

5. 传递任意数量的参数

5.1 结合使用位置参数(必选参数)和任意数量参数(*args)

有时候你并不知道要向函数传递多少个参数,比如制作披萨,你不知道顾客要多少种配料,此时使用带一个星号(*)的形参,来定义函数:

从结果可以看出,以可变参数的方式传入值时,Python将值封装成了一个元组,即使是只传入了一个值。

补充:多个参数都在一个列表里面,如果一个元素一个元素的传递,则代码会很难看,可以使用如下方式传递参数,任以上述make_pizza()函数为例:

在后面的“任意关键字参数”小节中,也可用这种方式传值,只不过得用双星号(**)。

注意:如果要让函数接收不同类型的参数,必须将可变参数放在最后,因为Python先匹配位置参数和关键字参数,再将剩余的参数封装到最后一个可变参数中。

5.2 使用任意数量的关键字参数(**kw)

有时候需要传入任意数量的参数,并且还要知道这些参数是用来干什么的,此时函数需要能够接受任意数量的关键字参数,这里使用双星号(**)来实现:

此处代码太长,后面没有截完,但不影响理解

从上述结果可以看出,Python将任意关键字参数封装成一个字典。这里也要注意,指示任意关键字参数的形参必须放到最后!

区分---命名关键字参数(也叫命名参数):

上述代码可以传递任意数量的关键字参数,但有时需要限制传入的关键字参数,比如上述build_profile()函数除了传入first和last这两个必选参数之外,还必须且只能传入age和country这两个参数(一个不多,一个不少)时,则需要用到命名关键字参数,它使用一个星号分隔必选参数和命名关键字参数,如下:

从以上结果可以看出命名关键字参数必须每个都赋值,可以有默认值,有默认值的可以不用再赋值;命名关键字之间可以交换顺序,如果要和前面的必选参数也交换顺序,则必须使用关键字参数的方式传递实参。

为什么有命名关键字参数:

(网上搜的答案,个人暂时认为这种参数可以被位置参数给替换掉)命名参数配合默认参数使用可以简化代码,比如在写类的构造函数时,有10个参数,8个有合理的默认值,那么可以将这8个定义为命名关键字参数,前两个就是必须赋值的位置参数。这样,在后面生成对象时,如果要替换默认值:

①要么按顺序给后面8个参数替换默认值(C++做法);

②要么用关键字参数的传值方式给这8个关键字不一定按顺序来赋值(Python做法);

③要么混合①②的做法,不过容易混淆。(也就是全用必选参数,前面一部分按顺序赋值,后面一部分用关键字参数赋值)

一点感想:但如果是笔者自己写代码,暂时更偏向于全用必选参数,带默认值,即如下定义形式:

而不是如下形式:

可能笔者才疏学浅,暂时还没领会到这种方式的精髓之处。

不过上述是没有可变参数的情况,如果是以如下形式定义函数:

在以如下形式调用时则会报错:

可以看出,Python在这里将test4解释为了位置参数,但笔者是想将其作为可变参数。所以笔者推测,在以下情况时,使用命名关键字参数比较好:

必选参数数量不少(其中有些参数的默认值不常变动),后面又跟有可变参数,由于必选参数很多,不容易记住位置,如果不用命名参数,按照上述关键字方式调用函数则会出错,所以此时将这些有合理默认值的必选参数变为命名关键字参数,则可以使用关键字参数不按顺序传值。但如果没有可变参数时,笔者还是倾向于使用带默认值的必选参数。

还有一点值得注意:命名关键字参数可以和可变参数(*args)混用,此时语法如下:

这里c, d为命名关键字参数,并且前面也不用加单个星号进行区分了,但是,如果和可变数量关键字参数(**kw)进行混用,命名关键字不能在可变数量关键字参数之前,即不存在如下函数定义形式:

如果这样定义,Pycharm会标红(其他IDE没用过,不知道提不提示)。

综上所述:Python中一共有五中参数类型,即必选参数(位置参数),默认参数(带默认值的参数),可变参数(*args),命名关键字参数和关键字参数(数量可变,**kw),这五种可以同时混用,但是必须遵照如下顺序:

(从左到右)必选参数、默认参数、可变参数、命名关键字参数和关键字参数。以下是这两个参数混用的几个例子:

常用的包含任意数量关键字,且不区分参数类型的函数定义方式如下:

6. 将函数存储在模块(Module)中

在python中,一个.py文件就是一个模块。使用模块的最大好处就是提高了代码的可维护性。其次,代码不用从零开始编写,一个模块编写完成后,可以在其他地方被调用。再次,可以避免函数名和变量名冲突,不同模块可以有相同的函数名和变量名。

6.1 导入整个模块

要让函数是可以导入的,得先创建模块。以上述make_pizza()函数为例,将其余代码删掉,只保留这一个函数,然后再在当前目录中创建一个making_pizzas.py的文件,执行如下代码以导入整个模块:

以这种方式导入模块时,按如下方式调用函数:

6.2 导入某模块中特定的函数

语法结构为:

仍以上述pizza.py为例:

6.3 模块补充

别名:

当函数名发生冲突,或者函数名、模块名太长时,可以取一个简短的名称,类似“外号”,以上述代码为例:

导入模块中的所有函数:

例如导入pizza模块中的所有函数:

然而,使用并非自己编写的大型模块时,最好不要采用这种导入方法,因为如果模块中有函数或变量和你自己写的函数、变量同名,结果将有问题。所以,一般的做法是要么只导入你需要的函数,要么导入整个模块并用句点表示法。

包:

Python中的包就是一个文件夹,但这个文件夹下面必须包含名为“__init__.py”的文件(前后都是双下划线),包中可以放多个模块,组织结构与Java包类似。

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

推荐阅读更多精彩内容

  • 第5章 函数和函数式编程 5.1 引言函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数...
    VIVAFT阅读 943评论 0 5
  • 赞赏自己:用接纳、爱来对待孩子,让孩子考前不焦虑!! 赞赏老公:与女儿考前谈心,让孩子勇敢的放手去考,不用临时抱佛...
    艾葭_阅读 186评论 0 0
  • 【南搜http://nan.so出品】 今儿一口气把《重返二十岁》和《奇怪的她》看了~ 【《重返二十岁》种子】 【...
    南搜阅读 1,051评论 0 1