Python学习笔记(4)之函数(一)

0.日常发牢骚

Screenshot

前几天,看到一起来北京的朋友发的说说,产生了极大的共鸣。本想着大四会是自由无拘无束的一年,后来发现我错了。。。每天的生活就是听不懂的研究生课,玩不了的LINUX,看不懂的论文,吃不上的饭...

生活真是太艰难了。。。

1.创建一个函数

函数、对象、模块都是Python中用来打包的工具,可以使整个代码显得简洁明了。

创建函数很容易,只需要通过def funcName():创建,调用时输入函数名即可。

>>> def myfun():
        print('这是我创建的第一个函数')

    
>>> myfun()
这是我创建的第一个函数

注意,在调用函数时,Python会自动向上寻找,下方的函数是不会被找到的。作为一个好习惯,可以把函数定义在最顶端,就像LaTex的引言区一样。

test()

def test():
    print('试图调用函数')
    
==================== RESTART: E:/python/codes/test.py====================
Traceback (most recent call last):
  File "E:/python/codes/test.py", line 1, in <module>
    test()
NameError: name 'test' is not defined

2.函数的参数

定义时函数后面的括号里可以加入参数,举一个最简单的例子:

>>> def myfun(number):
        print('输入的数字是:',number)

    
>>> myfun(8)
输入的数字是: 8

2.1 形参和实参

函数定义过程中的参数叫“形参”(parameter),它只是一个形式,表示占据一个参数位置;传递进来的参数称为“实参”(argument),它是具体的参数值。

比如上面的代码块中,number是形参,而8是实参。

2.2 关键字参数

有些函数会有许多许多参数,给这些参数赋值时必须按顺序进行,比如:

>>> def quotes(name,words):
        print(name+ '说:' + words)

>>> quotes('高尔基','书是人类进步的阶梯')
高尔基说:书是人类进步的阶梯

如果顺序错误,就会出现问题

>>> quotes('书是人类进步的阶梯','高尔基')
书是人类进步的阶梯说:高尔基

当参数很多时,往往不容易记清顺序,关键字参数便可以解决这个问题。只需要在调用参数时带上形参,即parameter=argument的形式,便可以忽略顺序。

>>> quotes(words='书是人类进步的阶梯',name='高尔基')
高尔基说:书是人类进步的阶梯

2.3 默认参数

在定义的函数里,只要有形参占据了参数位,在调用时就必须输入相应参数,否则会报错,提示“缺少参数”。我们可以给函数定义缺省时的默认参数,这样省去很多麻烦。设置默认参数只需在定义函数时的参数后面赋值。

>>> def myfun(number='没有输入数字'):
        print('输入的数字是:',number)

>>> myfun()
输入的数字是: 没有输入数字

>>> myfun(8)
输入的数字是: 8

2.4 收集参数(可变参数)

出现这种参数的原因是有时作者也搞不清到底需要多少个参数,所以就出现了收集参数。定义收集参数只需要在参数前加*即可。在例子中看一下:

>>> def myfun(*paraments):
        print('参数的长度为:', len(paraments))
        print('第二个参数是:',paraments[1])

    
>>> myfun(1,'哈哈哈',int,3.14)
参数的长度为: 4
第二个参数是: 哈哈哈

如果我们看一下print()的doc文件的话会发现,定义print的第一个参数就是收集参数(如下)。这符合我们日常使用print的习惯。

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

如果函数里同时出现收集参数和普通参数,要么将普通参数放在前面,按顺序引用;要么就要用关键字参数给普通参数赋值。

>>> def myfun(para1,*paraments):
        print('参数的长度为:', len(paraments))
        print('第二个参数是:',paraments[1])
        print(para1)

    
>>> myfun(1,'哈哈哈',int,3.14)
参数的长度为: 3
第二个参数是: <class 'int'>
1
>>> def myfun(*paraments,para1,):
        print('参数的长度为:', len(paraments))
        print('第二个参数是:',paraments[1])
        print(para1)

    
>>> myfun(1,'哈哈哈',int,para1=3.14)
参数的长度为: 3
第二个参数是: 哈哈哈
3.14
>>> def myfun(*paraments,para1,):
        print('参数的长度为:', len(paraments))
        print('第二个参数是:',paraments[1])
        print(para1)

    
>>> myfun(1,'哈哈哈',int,3.14)
Traceback (most recent call last):
  File "<pyshell#53>", line 1, in <module>
    myfun(1,'哈哈哈',int,3.14)
TypeError: myfun() missing 1 required keyword-only argument: 'para1'
        #报错:缺失参数

3. 返回值

符合一般情况下对函数的认知,函数有输入值和输出值。定义输出值只需函数内用return即可。

>>> def add(num1 , num2):
        return num1 + num2

>>> x = add(1,2)
>>> print(x)
3

注:

  1. 若是想要返回多个值,只需要return一个列表或者元组就OK了。
>>> def back():
        return [1,'嘻嘻',int]

>>> temp = back()
>>> print(temp)
[1, '嘻嘻', <class 'int'>]
>>> def back():
        return 1,'嘻嘻',int

>>> temp = back()
>>> print(temp)
(1, '嘻嘻', <class 'int'>)
>>> type(temp)
<class 'tuple'>
  1. Python里的函数是可以没有返回值的。没有返回值时,会自动返回None
>>> def back():
    print(1234)

    
>>> temp = back()
1234     #这里的1234不是函数的返回值,而是函数内部的命令
>>> print(temp)
None
>>> type(temp)
<class 'NoneType'>

4. 全局变量&局部变量

全局变量(Global Variable):在整个py文件中声明,全局范围内都可以访问;

局部变量(Local Variable):在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了。

画个图的话大概是这样?

4.1 读取

从上面的抽象派图中就能看出,函数中可以读取全局变量,而局部变量出了函数就被抹掉了,在函数外无法读取。

>>> def test():
        print(x)
    
>>> x=1
>>> test()
1
def test():
    x = 1
    print(x)

test()
print(x)
==================== RESTART: E:\python\codes\test.py ====================
1
Traceback (most recent call last):
  File "E:\python\codes\test.py", line 6, in <module>
    print(x)
NameError: name 'x' is not defined

4.2 修改

若要修改全局or局部变量时,就会出现一些比较神奇的事情。

因为在函数外是读取不到函数内的变量值的,所以也就不存在修改这一说。但是函数内可以读取全局变量,若要试图在函数内修改全局变量会发生什么呢?事实上,像上面的图中画的,函数内部可以看作是一个独立的空间,要是试图在函数内修改某个全局变量,Python会使用屏蔽(shadowing)的方式保护全局变量,即在这个独立空间里寻找(创建)一个和原来变量同名的新的局部变量,修改的也是这个局部变量。举个例子:

def test():
    x = 1
    print('修改后x在函数内的值是:', x)

x=5
test()
print('修改后x在函数外的值是:', x)

==================== RESTART: E:\python\codes\test.py ====================
修改后x在函数内的值是: 1
修改后x在函数外的值是: 5

可见全局变量x并没有被修改,并且在函数内打印的变量x是一个新的局部变量。再看下面的例子:

def test():
    x *= x

x=10
test()

==================== RESTART: E:\python\codes\test.py ====================
Traceback (most recent call last):
  File "E:\python\codes\test.py", line 5, in <module>
    test()
  File "E:\python\codes\test.py", line 2, in test
    x *= x
UnboundLocalError: local variable 'x' referenced before assignment
>>> print(x)
10

这个例子更直接的说明了:当在函数内部修改x的值时,Python会寻找函数内部叫x的变量,然后没有找到就报错了,而全局变量x安然无恙。

4.3 global关键词

之前说若是试图在函数内修改某个全局变量,Python会使用屏蔽(shadowing)的方式保护全局变量。若想在函数内部修改全局变量,就要使用global声明全局变量。

def test():
    global x
    x = 10
    print('函数内x的值为:', x)

x=5
test()
print('全局变量x的值为:', x)
==================== RESTART: E:\python\codes\test.py ====================
函数内x的值为: 10
全局变量x的值为: 10

这样就在函数内部将全局变量x的值修改了。下面的例子也说明了这一情况。

def test():
    global x
    x *= x

x=5
test()
print('打印x的值为:', x)
==================== RESTART: E:\python\codes\test.py ====================
打印x的值为: 25

4.3 nonlocal关键词

nonlocal在某些情况下也能起到和global相似的作用,因为需要用到内嵌函数,就放在后面再写。

函数内容太多了,本想在中秋之前截稿,发现完成不了,剩下的就放在下一期写吧,祝大家中秋快乐哈!


往期回顾

Python学习笔记(0)之Hello,python!
Python学习笔记(1)之列表list
Python学习笔记(2)之元组、字典&集合
Python学习笔记(3)之字符串string

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