def test1(): print('in the test1') def test(): print('in the test') return test1 res=test() print(res())
# 1.函数的定义:
# 1.test1是一个函数,当它被调用时,会打印出'in the test1'。
# 2.test是另一个函数,当它被调用时,会先打印出'in the test',然后返回test1函数对象本身,而不是调用test1函数。
# 2.函数的调用:
# 1.当你执行res = test()时,你实际上是在调用test函数。test函数执行了其体内的打印语句,并返回了test1函数对象。这个对象被赋值给了变量res。
# 3.返回值:
# 1.test函数的返回值是test1函数对象。这意味着res变量现在引用的是test1函数,而不是test1函数的执行结果。
# 4.通过res调用test1函数:
# 1.最后,当你执行print(res())时,你实际上是在调用res所引用的test1函数。因为res是test1的引用,所以res()等同于test1(),这会打印出'in the test1'。
# 这段代码展示了函数的高阶用法,即函数可以作为其他函数的返回值。这在Python中是非常有用的,因为它允许你创建可重用的代码块,这些代码块可以在需要时以函数的形式传递和调用。
#这段代码展示了函数的高阶用法,即函数可以作为其他函数的返回值。这在Python中是非常有用的,因为它允许你创建可重用的代码块,这些代码块可以在需要时以函数的形式传递和调用。
# name ='alex'
# def foo():
# name='zhugeliang'
# def bar():
# print(name)
# bar()
# foo()
name ='alex' def foo(): name='zhugeliang' def bar(): name='guanyunchang' print(name) return bar a=foo() print(a) a()
# 作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变
# 例一: name='alex' def foo(): name='lhf' def bar(): print(name) return bar func=foo() func() # 例二: name='alex' def foo(): name='lhf' def bar(): name='guozixin' def tt(): print(name) return tt return bar func=foo() func()()
# 匿名函数
# 匿名函数就是不需要显式的指定函数
def calc(x): return x+1 res=calc(10) print(calc(10)) func=lambda x:x+1 #匿名函数 print(func(10)) #输出alex_gae name='alex' def change_name(x): return name+"_age" res=change_name(name) print(res) fucn=lambda x:name+'_age' res=fucn(name) print('匿名函数的运行结果',res) lambda x:name+'_age' #和其他函数一起使用 func=lambda x,y,z:x+y+z print(func(1,2,3)) lambda x,y,z:(x+1,y+1,z+1) print(func(1,2,3))
#编程的方法论:
# 1.面向过程:
# 2.函数式
# 3.面向对象
# 一、函数式编程
# 函数的参数传入,是函数吃进去的食物,而函数return的返回值,是函数拉出来的结果,面向过程的思路就是,
# 把程序的执行当做一串首尾相连的函数,一个函数吃,拉出的东西给另外一个函数吃,另外一个函数吃了再继续拉给下一个函数吃。
# 例如:
# 用户登录流程:前端接收处理用户请求-》将用户信息传给逻辑层,逻辑词处理用户信息-》将用户信息写入数据库
# 验证用户登录流程:数据库查询/处理用户信息-》交给逻辑层,逻辑层处理用户信息-》用户信息交给前端,前端显示用户信息
# 二、什么是面向过程
# 面向过程是一种思维方式。当试图通过面向过程解决问题时,我们的关注点在于问题解决的流程,重在这个过程的控制,
# 需要用大量的模块(模块化的思想源自于硬件,在C语言中是函数)将大问题拆解,程序员通过控制模块的执行顺序以解决问题。
# 举个例子,当我们解决一个“如何将大象装入冰箱?”的问题时,最简单的解决思路是面向过程解决:
# 1、关注过程,将大问题拆解为小问题,实现每个小问题的解决方法
# a、打开冰箱门
# b、将大象装入冰箱
# c、关闭冰箱门
# 2、通过控制代码,控制模块执行,执行顺序为a->b->c,问题解决。
# 在日常生活或者说日常编程中,简单的问题用面向过程的思路解决,更加直接有效,但是当问题的规模稍大时,
# 如要描述三万个人吃饭的问题,或者要构建一个航空母舰模型的时候,用面向过程的思想是远远不够的。
# 而且面向过程程序的代码复用性、可扩展性、可移植性、灵活性、健壮性都会在处理大规模问题中出现问题。
# 函数式编程(Functional Programming)是一种编程范式,它将计算机运算视为数学上的函数计算,并避免使用程序状态以及易变对象。
# 这种编程范式强调函数作为一等公民,即函数可以赋值给变量、作为参数传入其他函数、或作为返回值返回。
# 函数式编程的基础是λ演算(lambda calculus),其中函数的函数可以作为输入和输出。
#
# 函数式编程的特点
# 无状态与数据不可变:函数式编程要求所有的数据都是不可变的,这意味着如果你想修改一个对象,
# 应该创建一个新的对象而不是修改已有的对象。这有助于简化程序的逻辑,减少错误的可能性。
# 高阶函数:高阶函数是指那些接受函数作为参数或返回函数的函数。这使得函数可以更加灵活地处理数据。
# 引用透明性:如果提供同样的输入,那么函数总是返回同样的结果,不依赖于外部状态的变化。这有助于验证程序的正确性。
# 惰性求值:惰性求值意味着表达式只在需要时才进行计算,这有助于节省计算资源。
# 函数式编程的应用
# GUI编程:通过明确的时间模型来简化图形用户界面(GUI)的编程。
# 机器人学:在机器人编程中,函数式编程可以帮助简化复杂的控制逻辑。
# 音乐编程:在音乐创作和生成中,函数式编程可以用来生成复杂的音乐结构。
# Web开发:在Web开发中,函数式编程可以帮助提高代码的可读性和可维护性。
# 函数式编程与命令式编程的区别
# 数据修改方式:函数式编程避免状态修改,而命令式编程允许修改数据状态。
# 错误处理:函数式编程通过纯函数减少错误的可能性,而命令式编程需要更多的错误处理机制。
# 代码结构:函数式编程倾向于使用更简洁的代码结构,而命令式编程可能包含更复杂的控制流程。
# 函数式编程的优点和缺点
# 优点:代码简洁、易于理解和维护,适合处理复杂的数据结构和算法。
# 缺点:可能不适合需要频繁修改状态的应用,且在某些情况下可能不如命令式编程高效。
# 通过了解函数式编程的基本概念、特点和应用场景,可以更好地理解这种编程范式的优势和局限性,从而在合适的场景中选择使用。
# Hashell clean erlang 学习方向
#三、面向对象编程
# 是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题的步骤中的行为。
# 面向对象编程(Object - Oriented Programming,简称OOP)则是一种以对象为中心的编程范式。在面向对象编程中,程序被组织成一组对象,每个对象都有自己的状态(属性)和行为(方法)。
# 对象是类的实例,类是定义对象的模板。这种编程风格强调将问题分解为对象,并通过对象之间的交互来解决问题。对象可以封装数据和相关的操作,具有良好的模块化和重用性。
# 面向过程编程:
# 1.不可改变数据
# 2.第一类对象
# 3.尾调用优化(尾递归)
# 列1,不可变,不用变量保存状态,不修改变量
#非函数式 a=1 def incr_test1(): global a a+=1 return a incr_test1() print(a)
#函数式 n=1 def incr_test2(n): return n+1 print(incr_test2(2)) print(n)
#高阶函数:满足如下之一即可 #1.把函数当作参数传给另外一个函数 def foo(n):#n=bar print(n) def bar(name): print('my name is %s' %name) # foo(bar) #把函数当作参数传给另外一个函数foo, foo(bar('alex')) #2.把函数自己返回给自己 def foo (): print('from foo') return foo #把函数自己返回给自己 foo() def bar(): print('from bar') def foo(): print('from foo') return bar n=foo() n()
# 尾调用优化
# 尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。
# 尾调用之所以与其他调用不同,就在于它的特殊的调用位置。
# 我们知道,函数调用会在内存形成一个"调用记录",又称"调用帧"(call frame),
# 保存调用位置和内部变量等信息。如果在函数A的内部调用函数B,那么在A的调用记录上方,
# 还会形成一个B的调用记录。等到B运行结束,将结果返回到A,B的调用记录才会消失。
# 如果函数B内部还调用函数C,那就还有一个C的调用记录栈,以此类推。所有的调用记录,
# 就形成一个"调用栈"(call stack)。
# 尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、
# 内部变量等信息都不会再用到了,只要直接用内层函数的调用记录,取代外层函数的调用记录就可以了。
#函数bar在foo内味尾调用 def bar(n): return n def foo(x): return bar(x) #函数bar1和bar2在foo内均为尾调用,二者在if判断条件不同的情况下都有可能作为函数的最后一步 def bar1(n): return n def bar2(n): return n+1 def foo(x): if type(x) is str: return bar1(x) elif type(x) is int: return bar2(x)
#函数bar 在foo 内尾非尾调用 def bar(n): return n def foo(x): y=bar(x) return y #调用bar在foo内味非尾调用 def bar(n): return n def foo(x): return bar(x)+1
标签:调用,函数,22,作用域,编程,foo,def,name From: https://www.cnblogs.com/liu-zhijun/p/18355818