初学者python笔记(函数)

函数可以说是每一门编程语言的灵魂,今天总结的内容就是函数方面的。
在编程中有这样三大编程方法论:
面向过程>>>找到解决问题的入口,按照一个固定的流程去模拟解决问题的流程
函数式>>>编程语言定义的函数 + 数学意义的函数(这是非常抽象的一类)
面向对象>>>重在用一个个对象的执行去实现想要的效果(常常与面向过程结合起来,这里有一篇文章,对面向对象有非常通俗易懂的解释和案例用生活案例让你明白面向对象)

  1. python中的函数参数
def test(x, *args):
	print(x)
	print(args)
	print(args[0][0])  #传入后就是一个元组,可以用索引来取值
#调用函数,并传入第二个参数为列表,函数则需要用一个带*的变量来接收,类似C语言的指针
test(1,['x','y','z'])  #当成一个列表整体传入,即元组中的列表
test(1,*['x','y','z'])  #拆开了传入,即元组中有3个元素

结果是:
1
([‘x’, ‘y’, ‘z’],)
x
1
(‘x’, ‘y’, ‘z’)
x
Ps:函数定义要习惯写在前面,因为python是从上往下执行,当你调用一个函数的时候这个函数必须是已经被定义过的,否则编译器会报错
比如这样:

def foo():
	print("from foo")
	bar()  #从上往下执行,此时bar()还未定义
foo()
def bar():
	print("from bar")
  1. 定义一个能接收任意值的函数
#接收字典
def test(x,**kwargs):  
	print(x)
	print(kwargs)
test(1,y=2,z=3)
#能接收任意值的函数
def test(x,*args,**kwargs):  #顺序不能变:固定列表在前,字典在后面
	print(x)
	print(args,args[-1])  #索引-1可以取到列表的最后一个元素
	print(kwargs,kwargs['y'])  #'y'这个key对应的value为2
test(1,1,1,2,3,4,y=2,z=3)  
#第一个1给x,中间数字给args列表,y=2,z=3给kwargs字典

结果是:
1
{‘y’: 2, ‘z’: 3}
1
(1, 1, 2, 3, 4) 4
{‘y’: 2, ‘z’: 3} 2

  1. 函数递归(就是函数中调用本身):但递归的效率不高
def calc(n):
    print(n)
    if int(n/2) == 0:
        return n 
    res = calc(int(n/2))  #再次调用calc()并将n除2转化成int类型后传入
    return res  #此步为终结步
r = calc(10)
print(r)
#稍微理一下里面的逻辑:
#传入10,输出10,10不满足if,将(10/2)=5传入calc();
#输出5,5不满足if,再传入(5/2)=2;
#输出2,2不满足if(因为2/2=1),传入1到calc();
#输出1,1满足if,返回1,并将返回值1赋值给res;
#注意,这是整个过程第一次返回值,在之前都只是传入值,没有返回
#最终再返回1,用r接收返回值,输出r

结果是:
10
5
2
1
1

  1. 函数作用域之函数中获取全局变量
    在函数中可以用全局变量,但要修改全局变量时,则需要用以下操作获取一下:
six = 'alex-54250'
def change_name():
    global six  #获取后才可以在函数中修改全局变量
    six = 'aaaa-54250'
    print(six)
change_name()
print(six)

结果是:
aaaa-54250
aaaa-54250
而且global这种修改是永久性的,不止是在函数内有效
下面这种就不会干扰全局变量的值,如果只在函数内用,就可以如此

name = '天呐'
def a():
    name = 'wangbadan'
    print(name)  #此处输出的就是'wangbadan'
a()
print(name)  #但全局变量不变,这里结果是'天呐'
  1. 只要test()有个括号,就一定会运行,不管有没有变量去接收返回值
    函数嵌套的调用一:
def test1():
	print('in the test1')
def test():
	print('in the test')
	return test1   #返回test1这个函数,并没有运行test1,没有返回值  
res = test()
#将test运行的返回值赋值给res,即将res()作为与test()返回值同等的函数,就是test1()(因为函数即变量)
print(res)
#输出res()函数的内存地址,即test1()的内存地址
print(res())
#运行res()函数即test1(),打印出in the test1,最后再打印test1()的返回值None
  1. 函数嵌套的调用二:
name = '天呐'
def foo():
    name = 'CMYK'  #没有获取全局变量,此处赋值无效
    def bar():
        name = 'on my god'
        print(name)
    return bar  #返回bar这个函数,但不运行bar()
a = foo()  #运行函数
print(a)
a()
#将foo的返回值bar赋值给a,使a()=bar(),(此过程没有调用bar()所以不会运行bar),
#再打印a即bar()/a()的内存地址,再运行a()即bar()打印出'wupeiqi',
#因为在bar()中输出的name局部变量name,也就是离bar()最近一级的name

结果是:
<function foo..bar at 0x002CC5D0>
on my god
若:

name = '天呐'
def foo():
	name = 'CMYK'
	def bar():
		#name = 'on my god'
		print(name)
	return bar
a = foo()
print(a)
a()

则结果是:
<function foo..bar at 0x0079C5D0>
CMYK
也就是调用bar()时,bar()内部无name的赋值,则使用name的最近一级变量’CMYK’,此变量仍然对全局变量无影响

  1. 函数嵌套的调用三:
def foo():
    name = '昨天'
    def bar():
        name = '今天'
        def tt(): 
            print(name)
        return tt  #这里是整个嵌套函数执行的第一步,返回tt这个函数,操作是输出name
    return bar  #第二步,bar内操作是输出'今天'
bar = foo()  #该bar与foo内的一样,因为bar是foo的返回值,bar()=bar()
tt = bar()
#该tt与bar内的一样,因为tt是bar的返回值,tt()==tt(),
#已将name赋值成'今天',但并没有调用tt(),故不会打印
print(tt)  #打印tt()这个函数的地址
tt()
#调用tt,因为tt内没有name的赋值,所以往上一级找,即name='今天',打印'今天'

#函数嵌套的调用:
foo()()()
#第一次运行foo返回bar,第二次运行bar并name='今天',返回tt,
#第三次运行tt并打印name

结果是:
<function foo..bar..tt at 0x02C1A5D0>
今天
今天

发布了17 篇原创文章 · 获赞 32 · 访问量 2000

猜你喜欢

转载自blog.csdn.net/Viewinfinitely/article/details/104497372