1. 函数概述 

  在编程的语境下,函数 (function) 是指一个有命名的、执行某个计算的语句序列 (sequence of statements) 。函数可以针对某类问题建立了通用解决步骤(算法),函数减少了重复代码,从而让程序更简洁、易读、易于操作。

  函数由对象、语句、表达式组成。

  函数执行特定的操作并返回一个值(无返回值则隐式返回 None)

  函数编程是面向过程的。

  Python函数代码结构和调用如下:

2. 变量

2.1  局部作用域与全局作用域、global语句

  如果全局作用域变量在局部作用域没有被定义(赋值,或者作为参数),则全局作用域变量可以被局部作用域读取

  1. >>> def func():
  2. print(a) # 这种写法是不好的
  3.  
  4. >>> a = 2 # a是全局作用域变量,但可以被局部作用域读取
  5. >>> func()
  6. 2

  如果变量在局部作用域中被定义了,则局部作用域不会再读取全局作用域的变量,如果在变量被定义前读取,则会引发错误,下面这个例子,Python 编译函数的定义体时, 会先判断 b 是局部变量, 因为在函数中给它赋值了。

  1. >>> b = 5
  2. >>> def func(a):
  3. print(a)
  4. print(b) # 尝试打印b变量出错,程序终止
  5. b = 8
  6.  
  7. >>> func(3)
  8. 3
  9. Traceback (most recent call last):
  10. File "<pyshell#6>", line 1, in <module>
  11. func(3)
  12. File "<pyshell#5>", line 3, in func
  13. print(b)
  14. UnboundLocalError: local variable 'b' referenced before assignment

  如果在函数中赋值时想让解释器把 b 当成全局变量, 要使用 global 语句声明:

  1. >>> b = 6
  2. >>> def func(a):
  3. global b # global语句声明了变量b为全局变量
  4. print(a)
  5. print(b)
  6. b = 8
  7.  
  8. >>> func(3)
  9. 3
  10. 6

2.2  闭包和自由变量、nonlocal语句

  自由变量(free variable),是指未在本地作用域中绑定的变量。如果自由变量绑定的值是可变的,则在闭包中仍然可以操作该变量,如果是不可变的(数字、字符串等),则在闭包中重新绑定自由变量会出错

  1. def make_averager():
  2. count = 0
  3. total = 0
  4. def averager(new_value):
  5. count += 1
  6. total += new_value
  7. return total / count
  8. return averager
  9.  
  10. >>> avg = make_averager()
  11. >>> avg(10)
  12. Traceback (most recent call last):
  13. ...
  14. UnboundLocalError: local variable 'count' referenced before assignment

  要让闭包把变量标记为自由变量,可以用nonlocal语句声明,nonlocal语句解决了上面的问题

  1. def make_averager():
  2. count = 0
  3. total = 0
  4. def averager(new_value):
  5. nonlocal count, total # 声明count、total为自由变量
  6. count += 1
  7. total += new_value
  8. return total / count
  9. return averager

2.2  变量赋值的一些经验(for循环中)

  在下面这个例子中,words = Regex2.sub(replace,words,1) 这一句实际上如同增强赋值,如果将words换为其他名称,如a或b等都得不到想要的结果,而且,这样做也省去后面读写文件的一些麻烦

  1. # (文件读写)疯狂填词2.py
  2.  
  3. '''
  4. 创建一个疯狂填词( Mad Libs)程序,它将读入文本文件, 并让用户在该文本
  5. 文件中出现 ADJECTIVE、 NOUN、 ADVERB 或 VERB 等单词的地方, 加上他们自
  6. 己的文本。例如,一个文本文件可能看起来像这样:
  7. The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN was
  8. unaffected by these events.
  9. 程序将找到这些出现的单词, 并提示用户取代它们。
  10. Enter an adjective:
  11. silly
  12. Enter a noun:
  13. chandelier
  14. Enter a verb:
  15. screamed
  16. Enter a noun:
  17. pickup truck
  18. 以下的文本文件将被创建:
  19. The silly panda walked to the chandelier and then screamed. A nearby pickup
  20. truck was unaffected by these events.
  21. 结果应该打印到屏幕上, 并保存为一个新的文本文件。
  22. '''
  23.  
  24. import re
  25.  
  26. def mad_libs(filename_path, save_path):
  27. with open(filename_path,'r') as strings: # 相对路径下的文档
  28. words = strings.read()
  29. Regex = re.compile(r'\w[A-Z]+') # \w :匹配1个任何字母、数字或下划线
  30. finds = Regex.findall(words)
  31. for i in finds:
  32. replace = input('输入你想替换 {} 的单词:\n'.format(i))
  33. Regex2 = re.compile(i)
  34. words = Regex2.sub(replace,words,1) # 这个变量必须要是words与上面一致否则只打印最后替换的一个,可以画栈堆图跟踪这个变量的值
  35. print(words)
  36.  
  37. # strings.close() 不用这一行,with 上下文管理器会自动关闭
  38.  
  39. with open(save_path,'a') as txt:
  40. txt.write(words + '\n') #分行写
  41. txt.close()
  42.  
  43. # save_txt = open('保存疯狂填词文档.txt','a')
  44. # save_txt.write(words)
  45. # save_txt.close()
  46.  
  47. if __name__ == '__main__':
  48. filename_path = input('输入要替换的txt文本路径:') # '疯狂填词原始文档.txt'
  49. save_path = input('输入要保存的文件路径(包含文件名称):') # '保存疯狂填词文档.txt'
  50. mad_libs(filename_path, save_path)

3. 参数

3.1  形参和实参

  在def语句中,位于函数名后面的变量通常称为形参,而调用函数时提供的称为实参。在函数内部重新关联参数(即绑定,也就是赋值)时,函数外部的变量不受影响。

  1. >>> def try_to_change(n):
  2. ... n = 'Mr. Gumby'
  3. ...
  4. >>> name = 'Mrs. Entity'
  5. >>> try_to_change(name)
  6. >>> name
  7. 'Mrs. Entity'

4. 栈堆图

  参考自《像计算机科学家一样思考Python》

  1. # 栈堆图.py
  2.  
  3. def print_twice ( bruce ):
  4. print ( bruce )
  5. print ( bruce )
  6.  
  7. def cat_twice (part1 , part2 ):
  8. cat = part1 + part2
  9. print_twice (cat)
  10.  
  11. line1 = 'Bing tiddle'
  12. line2 = 'tiddle bang .'
  13.  
  14. cat_twice (line1 , line2 )

1. 每个函数用一个栈帧 (frame) 表示。一个栈帧就是一个线框,函数名在旁边,形参以及
函数内部的变量则在里面。前面例子的堆栈图如图 3.1所示。
2. 这些线框排列成栈的形式,说明了哪个函数调用了哪个函数等信息。在此例中,print_twice
被 cat_twice 调用,cat_twice 又被 __main__ 调用,__main__ 是一个表示最上层栈帧的特殊名
字。当你在所有函数之外创建一个变量时,它就属于 __main__。
3. 每个形参都指向其对应实参的值。因此,part1 和 line1 的值相同,part2 和 line2 的值相
同,bruce 和 cat 的值相同。
4. 如果函数调用时发生错误,Python 会打印出错函数的名字以及调用它的函数的名字,以
及调用后面这个函数 的名字,一直追溯到 __main__ 为止。
例如,如果你试图在 print_twice 里面访问 cat ,你将获得一个 NameError :
5. 这个函数列表被称作回溯 (traceback) 。它告诉你发生错误的是哪个程序文件,错误在
哪一行,以及当时在执行哪个函数。它还会显示引起错误的那一行代码。
回溯中的函数顺序,与堆栈图中的函数顺序一致。出错时正在运行的那个函数则位于回
溯信息的底部。

3. 函数代码实践(源自《Python编程快速上手  让繁琐工作自动化》)

  1. '''
  2. 编写一个名为 collatz()的函数,它有一个名为 number 的参数。如果参数是偶数,那么 collatz()就打印出 number // 2, 并返回该值。
  3. 如果 number 是奇数, collatz()就打印并返回 3 * number + 1。
  4. 让用户输入一个整数, 并不断对这个数调用 collatz(), 直到函数返回值1
  5. (令人惊奇的是, 这个序列对于任何整数都有效, 利用这个序列,你迟早会得到 1! 既使数学家也不能确定为什么。 你的程序在研究所谓的“Collatz序列”,
  6. 它有时候被称为“最简单的、 不可能的数学问题”)。
  7. 在前面的项目中添加 try 和 except 语句,检测用户是否输入了一个非整数的字符串。正常情况下, int()函数在传入一个非整数字符串时,会产生 ValueError 误,
  8. 比如 int('puppy')。在 except 子句中,向用户输出一条信息,告诉他们必须输入一个整数。
  9. '''
  10.  
  11. def collatz(number):
  12. if number == 1:
  13. return 1
  14. elif number % 2 == 0:
  15. numbers = number // 2
  16. print(numbers)
  17. collatz(numbers)
  18. elif number % 2 == 1:
  19. numbers = 3*number + 1
  20. print(numbers)
  21. collatz(numbers)
  22. try:
  23. number = int(input("请输入一个整数->:"))
  24. collatz(number)
  25. except ValueError:
  26. print("please input a integer number")

Python:函数解释(面向过程)的更多相关文章

  1. Python函数之面向过程编程

    一.解释 面向过程:核心是过程二字,过程即解决问题的步骤,基于面向过程去设计程序就像是在设计,流水线式的编程思想,在设计程序时,需要把整个流程设计出来, 一条工业流水线,是一种机械式的思维方式 二.优 ...

  2. python基础(23):面向过程与面向对象的优劣、初识面向对象

    1. 面向过程与面向对象的优劣 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程 ...

  3. Python 面向对象和面向过程对比

    # 大象装冰箱 # 脚本, 此时代码是最简单的. 不需要构思整个程序的概况 print("开门") print("装大象") print("关门&qu ...

  4. python函数的执行过程

    对于 Python 常规函数,都只有一个入口,但会有多个出口如 return 返回或者抛出异常.函数从入口进入会一直运行到 return 语句或者抛出异常,中间不会暂停,函数一直拥有控制权.当运行结束 ...

  5. day20 函数收尾+面向过程+模块

    目录 一.算法(二分法) 二.面向过程与函数式 1 编程范式/思想 2 面向过程 3 函数式 3.1 匿名函数与lambda 三.模块 1 什么是模块 2 为何要有模块 3 怎么用模块 3.1第一次导 ...

  6. Day5_协程函数_面向过程

    def func(count): while True: yield count count +=1 #这是一个生成器,需要利用next()来执行. func(10) #yield: #1.把函数的执 ...

  7. python面向对象和面向过程介绍与区别

    一.面向对象和面向过程的区别: a.面向过程: 1)根据业务逻辑从上到下写代码 2)开发思路是将数据和函数按照执行的逻辑顺序组织在一起 3)分开考虑数据与函数 定义性文字: 面向对象编程(Object ...

  8. Python基础之面向过程编程

    要求:在文件里递归找到关于包含“Python”内容的文件的绝对路径并打印出来 #定义阶段 import os,time def init(func): #装饰器的作用是使下面的生成器初始化,yield ...

  9. python基础之面向过程编程,模块

    面向过程编程 面向过程的核心是过程,指的是解决问题的步骤,即先干什么再干什么,就好像设计一条流水线. 优点:复杂的问题流程化,进而简单化 缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身 ...

  10. Python 迭代器-生成器-面向过程编程

    上节课复习:1. 函数的递归调用 在调用一个函数的过程中又直接或者间接地调用了函数本身称之为函数的递归 函数的递归调用有两个明确的阶段: 1. 回溯 一层一层地调用本身 注意: 1.每一次调用问题的规 ...

随机推荐

  1. Python 装饰器原理剖析

    以下内容仅用于帮助个人理解装饰器这个概念,案例可能并不准确. 什么是装饰器? 我们知道iPhone 应用商店中有成千上万的APP,我们也知道苹果系统每年都会大版本更新增加很多新功能.这些功能要想发挥出 ...

  2. 最佳搭档:利用 SSH 及其配置文件节省你的生命

    本文转载自最佳搭档:利用 SSH 及其配置文件节省你的生命 导语 SSH 协议是事实上的互联网基石之一.在 SSH 协议出现之前(1995 年由 Tatu Ylonen 设计),通过互联网远程登录其他 ...

  3. 创建一个springboot项目

    进入https://start.spring.io/ 再点击GENERATE,下载解压即可 注意配置好阿里云的仓库镜像,免得依赖无法下载 不下载最新版springboot是因为我在测试中遇到了问题,貌 ...

  4. 解决异常: Execution default-cli of goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.7:generate failed: Cannot instantiate object of type tk.mybatis.mapper.generator.MapperPlugin -> [Help 1]

    mybatis-generator整合通用mapper使用generator插件生成model.mapper时报错: 产生以下错误:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 解决办法: ...

  5. Windows 环境下搭建 RocketMQ

    Apache 官网: http://rocketmq.apache.org/ RocketMQ 的 Github 地址: English:https://github.com/apache/rocke ...

  6. 看完我的笔记不懂也会懂----Node.js

    Node.js 学习 - 命令行窗口 - 进程与线程 - ECMAScript的缺点 - Node模块化 - Node中的全局对象 - 包 package - NPM包管理器 (Node Packag ...

  7. 数组的常用方法之split

    今天我们来聊一下数组的常用方法:split 返回值:一个新数组. 1.该方法可以直接调用不传任何值,则会直接将字符串转化成数组. var str = 'I love Javascript'; cons ...

  8. 使用CSS计数器美化数字有序列表

    在web设计中,使用一种井井有条的方法来展示数据是十分重要的,这样用户就可以很清晰的理解网站所展示的数据结构和内容,使用有序列表就是实现数据有组织的展示的一种简单方法. 如果你需要更加深入地控制有序列 ...

  9. SpringBoot利用spring.profiles.active=@spring.active@不同环境下灵活切换配置文件

    一.创建配置文件 配置文件结构:这里建三个配置文件,application.yml作为主配置文件配置所有共同的配置:-dev和-local分别配置两种环境下的不同配置内容,如数据库地址等. appli ...

  10. 182. 查找重复的电子邮箱 + group by + having

    182. 查找重复的电子邮箱 LeetCode_MySql_182 题目描述 方法一:使用笛卡尔积 # Write your MySQL query statement below select di ...