【Python pro】函数

打印 上一主题 下一主题

主题 866|帖子 866|积分 2598

1、函数的定义及调用

1.1 为什么必要函数

   

  • 进步代码复用性——封装
  • 将复杂问题分而治之——模块化
  • 利于代码的维护和管理
  1.1.1 顺序式

  1. n = 5
  2. res = 1
  3. for i in range(1, n+1):
  4.     res *= i
  5. print(res)
  6. # 输出:120
复制代码
1.1.2 抽象成函数

  1. def factorial(n):
  2.     res = 1
  3.     for i in range(1, n+1):
  4.         res *= i
  5.     return res
  6. print(factorial(5))
  7. # 输出:120
复制代码
1.2 函数定义及调用

   

  • 白箱子:输入,处理,输出
  • 三要素:参数、函数体、返回值
  1.2.1 定义

   模块——def 函数名(参数):
      函数体
      return 返回值
  1. def area_of_square(n):
  2.     area = pow(n, 2)
  3.     return area
复制代码
1.2.2 调用

   模块——函数名(参数)
  1. area = area_of_square(5)
  2. print(area)
  3. # 输出:25
复制代码
1.3 参数传递

1.3.1 形参和实参

(1)形参:

   函数定义时的参数,本质上是变量名
  (2)实参:

   函数调用时的参数,本质上是变量值
  1.3.2 位置参数

   

  • 要求:严酷按照位置顺序,用实参对形参举行赋值
  • 适用:通常在参数比力少时
  • 注意:实到场形参个数必须一一对应,不多不少
  1. def function(x, y, z):
  2.     print(x, y, z)
  3. function(1, 2, 3)
  4. # 输出:1 2 3
  5. function(1, 2, 3, 4)
  6. # 输出:TypeError: function() takes 3 positional arguments but 4 were given
复制代码
1.3.3 关键字参数

   

  • 模板:形参名=实参值
  • 适用:通常在参数比力多时
  • 要求:实到场形参必须一 一对应
  1. def function(x, y, z):
  2.     print(x, y, z)
  3. function(x=1, z=2, y=3)
  4. # 输出:1 3 2
复制代码


  • 位置参数可以和关键字参数混用,但位置参数必须在关键字参数之前
  1. function(1, z=2, y=3)
  2. # 输出:1 3 2
  3. function(x=1, 2, z=3)
  4. # 输出:SyntaxError: positional argument follows keyword argument
复制代码


  • 不能为同一个形参重复传值
  1. function(1, z=2, x=3)
  2. # 输出:TypeError: function() got multiple values for argument 'x'
复制代码
1.3.4 默认参数

   

  • 定义:默认参数是编程语言中函数定义的一种特性,它允许在声明函数时为参数指定一个默认值。如果调用函数时没有提供该参数的值,则使用默认值。
  

  • 默认参数必须在非默认参数后面
  • 调用函数时,可不对默认参数的形参传值
  1. def greet(name, message="你好, "):
  2.     print(f"{message}{name}")
  3. # 使用默认的message参数
  4. greet("小李")
  5. # 输出:你好, 小李
  6. # 覆盖默认的message参数
  7. greet("小张", "欢迎你, ")
  8. # 输出:欢迎你, 小张
复制代码


  • 默认参数应设置为不可变类型(数字、字符串、元组)
  1. def add_item(item, my_list=[]):
  2.     my_list.append(item)
  3.     return my_list
  4. print(add_item('apple'))
  5. # 输出: ['apple']
  6. print(add_item('banana'))
  7. # 输出: ['apple', 'banana']
  8. def add_item(item, my_list=None):
  9.     if my_list is None:
  10.         my_list = []
  11.     my_list.append(item)
  12.     return my_list
  13. print(add_item('apple'))
  14. # 输出: ['apple']
  15. print(add_item('banana'))
  16. # 输出: ['banana']
复制代码


  • 参数可选
  1. def name(first_name, last_name, middle_name=None):
  2.     if middle_name:
  3.         return first_name + middle_name + last_name
  4.     else:
  5.         return first_name + last_name
  6. print(name("王", "源"))
  7. # 输出:王源
  8. print(name("王", "凯", "俊"))
  9. # 输出:王俊凯
复制代码
1.3.5 可变长参数——args和kwargs

   

  • 定义:允许函数接受恣意数量的位置参数和关键字参数
  • 用途:当你不确定一个函数将吸收多少个参数时
  (1)*args:

   传递一个非键值对的可变数量的参数列表给函数。星号(*)表现将参数应该视为元组来处理
  1. def test_var_args(f_arg, *argv):
  2.     print("第一个常规参数:", f_arg)
  3.     print(argv)
  4.     for arg in argv:
  5.         print("另一个通过*args传入的参数:", arg)
  6. test_var_args('Python', 'Rocks', 'For', 'Data', 'Science')
  7. # 输出:第一个常规参数: Python
  8. #      ('Rocks', 'For', 'Data', 'Science')
  9. #      另一个通过*args传入的参数: Rocks
  10. #      另一个通过*args传入的参数: For
  11. #      另一个通过*args传入的参数: Data
  12. #      另一个通过*args传入的参数: Science
复制代码
(2)*kwargs:

   允许将不定长度的键值对作为参数传递给一个函数。双星号(**)表现将参数视为字典来处理
  1. def greet_me(**kwargs):
  2.     print(kwargs)
  3.     for key, value in kwargs.items():
  4.         print("{0} = {1}".format(key, value))
  5. greet_me(name="小李", age=25, city="北京")
  6. # 输出:{'name': '小李', 'age': 25, 'city': '北京'}
  7. #      name = 小李
  8. #      age = 25
  9. #      city = 北京
复制代码
1.4 函数体和变量作用域

   

  • 函数体:指在定义一个函数时,包含在函数声明和结束之间的所有代码块
  • 局部变量:在函数内部定义的变量,其作用范围仅限于定义它的函数内部,不能在函数外部被访问或修改
  • 全局变量:在所有函数之外定义的变量,可以在文件的任何地方被访问(包括所有函数内部)
  1. # 定义一个全局变量
  2. global_var = "我是全局变量"
  3. def check_scope():
  4.     # 定义一个局部变量
  5.     local_var = "我是局部变量"
  6.     print(local_var)  # 可以访问局部变量
  7.     # 输出:我是局部变量
  8.     """
  9.     # 访问全局变量
  10.     print(global_var)
  11.     # 输出:UnboundLocalError: cannot access local variable 'global_var' where it is not associated with a value
  12.     """
  13.     # 尝试修改全局变量的值,不使用global时会创建一个新的局部变量
  14.     global_var = "尝试修改全局变量失败"
  15.     print(global_var)
  16.     # 输出:尝试修改全局变量失败
  17. def modify_global_var():
  18.     global global_var  # 使用global关键字声明我们要使用全局变量
  19.     global_var = "全局变量已被修改"
  20.     print(global_var)
  21.     # 输出:全局变量已被修改
  22. # 调用函数
  23. check_scope()
  24. print(global_var)
  25. # 输出:我是全局变量
  26. modify_global_var()
  27. print(global_var)
  28. # 输出:全局变量已被修改
  29. """
  30. # 在函数外部无法访问局部变量
  31. print(local_var)
  32. # 输出:NameError: name 'local_var' is not defined. Did you mean: 'global_var'?
  33. """
复制代码
1.5 返回值

1.5.1 单个返回值

  1. def function(x):
  2.     return x**3
  3. res = function(2)
  4. print(res)
  5. # 输出:8
复制代码
1.5.2 多个返回值

  1. def function1(x):
  2.     return x, x**2, x**3
  3. print(function1(2))
  4. # 输出:(2, 4, 8)
  5. a, b, c = function1(3)
  6. print(a, b, c)
  7. # 输出:3 9 27
复制代码
1.5.3 多个return语句(只执行此中一个)

  1. def function2(x):
  2.     if x in ['Sunday', 'Saturday']:
  3.         return "weekend"
  4.     else:
  5.         return "weekday"
  6.     print("这一句根本没有机会不执行")
  7. print(function2('Saturday'))
  8. # 输出:weekend
  9. print(function2('Monday'))
  10. # 输出:weekday
复制代码
1.5.4 没有return语句(返回值为None)

  1. def function3(x):
  2.     print("没有返回值")
  3. print(function3(1))
  4. # 输出:没有返回值
  5. #      None
复制代码
2、匿名函数

2.1 基本形式

   lambda 变量:
  函数体
  2.2 常见用法

2.2.1 排序——sort()/sorted()

  1. ls = [(98, 88), (78, 99), (86, 74), (90, 90), (78, 96)]
  2. ls.sort()  # 基于每个元组的第一个元素进行排序
  3. print(ls)
  4. # 输出:[(78, 96), (78, 99), (86, 74), (90, 90), (98, 88)]
  5. ls.sort(key=lambda x: x[1])  # 基于每个元组的第二个元素进行排序
  6. print(ls)
  7. # 输出:[(86, 74), (98, 88), (90, 90), (78, 96), (78, 99)]
  8. ls1 = sorted(ls, key=lambda x: x[1]+x[0], reverse=True)
  9. print(ls1)
  10. # 输出:[(98, 88), (90, 90), (78, 99), (78, 96), (86, 74)]
复制代码
2.2.2 最值——max()/min()

  1. ls2 = max(ls, key=lambda x: x[1])
  2. print(ls2)
  3. # 输出:(78, 99)
  4. ls3 = min(ls, key=lambda x: x[1])
  5. print(ls3)
  6. # 输出:(86, 74)
复制代码
3、面向过程和面向对象

3.1 面向过程

3.1.1 定义

   一种编程范式,通过一系列的过程或函数来组织代码
  3.1.2 关注

   “怎么做”,即如何一步步地解决问题
  3.1.3 特点

(1)流程控制:

   步调由一系列顺序执行的语句组成,包括条件判定、循环等
  (2)模块化:

   将代码分解为多个函数或过程,每个函数或过程负责完成一个特定的任务
  (3)数据与操作分离:

   数据和对数据的操作通常是分开定义的。函数吸收数据作为参数,处理后大概返回结果
  (4)易于理解和实现:

   对于简单的任务大概逻辑较为直接的问题,面向过程的方法通常更加直观易懂
  1. def calculate_area(radius):
  2.     pi = 3.14159
  3.     return pi * (radius**2)
  4. def main():
  5.     r = 5
  6.     area = calculate_area(r)
  7.     print("半径为", r, "的圆的面积为:", area)
  8. main()
  9. # 输出:半径为 5 的圆的面积为: 78.53975
复制代码
3.2 面向对象

3.2.1 定义

   一种基于“对象”概念的编程范式,对象可以包含数据(属性)和方法(举动)
  3.2.2 关注

   “是什么”,即把问题分解成一组相互关联的对象,每个对象都是某个类的实例
  3.2.3 特点

(1)封装:

   将数据和操作数据的方法捆绑在一起,隐蔽内部状态,并要求所有交互都通过对象的公开接口举行
  (2)继承:

   一个类可以从另一个类继承属性和方法,这促进了代码重用并允许创建条理结构
  (3)多态:

   允许子类提供其父类方法的差别实现,使得同一类型的对象可以以差别的方式响应类似的方法调用
  (4)抽象:

   简化复杂性的一种战略,通过隐蔽具体的实现细节,只暴露必要的功能给用户
  1. class Circle:
  2.     def __init__(self, radius):
  3.         self.radius = radius
  4.     def calculate_area(self):
  5.         pi = 3.14159
  6.         return pi * (self.radius ** 2)
  7. def main():
  8.     c = Circle(5)
  9.     print("半径为", c.radius, "的圆的面积为:", c.calculate_area())
  10. main()
  11. # 输出:半径为 5 的圆的面积为: 78.53975
复制代码
3.3 区别

3.3.1 设计理念

   面向过程编程注重算法的设计,而面向对象编程更关心数据结构的设计及其上的操作
  3.3.2 扩展性

   由于封装、继承和多态的存在,面向对象编程更轻易扩展和维护,特别是在大型项目中
  3.3.3 复用性

   面向对象编程通过类和继承机制进步了代码的复用性,淘汰了重复代码
  3.3.4 适用场景

   面向过程编程得当解决小规模、线性的任务;面向对象编程更得当于构建大型、复杂的软件系统,尤其是那些必要恒久维护和发展的情况
  
微语录:万物皆有裂缝,那是光照进来的地方。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表