首页 > 编程语言 >Python函数(1)--自定义函数与作用域

Python函数(1)--自定义函数与作用域

时间:2024-07-14 16:59:28浏览次数:8  
标签:函数 自定义 作用域 sum 参数 print def

函数的定义

Python中的函数是一段组织好的、可重复使用的、用来实现单一或相关联功能的代码块。函数能提高应用的模块性,和代码的重复可用性。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被称为用户自定义函数。

自定义函数

假设,我们现在求一个半径为6.5的圆的面积,怎么求?

正常编写是不是先给一个整数型半径,然后求半径与PI的乘积:

PI = 3.14
#求⚪的面积
r = 5.6
s = PI * r * r
print(s)

这样,我们就求得了圆的面积。好的,那现在半径变了,求一个半径为8、为10、为20的圆的面积,我们反复的将半径给替换掉是不是很麻烦呢?可不可以有一个函数能够让我输入半径就能直接得到圆的面积呢?那我们自己来定义一个求圆面积的的函数看看:

我们该怎么定义一个函数呢?

函数定义的规则:

  1. 函数代码块以 def 关键词开头,后接函数名称和圆括号 ()
  2. 如果需要传入参数(变量),可在圆括号内定义
  3. 函数的第一行语句可以选择性地使用文档字符串——用于存放函数说明
  4. 函数内容以冒号 : 起始,并且缩进
  5. 可选择性地使用return返回一个值给调用方,不 return 相当于返回 None
  6. 注意:在Python中不需要定义返回值类型,可自动推断

格式

def circle_area(r):
    '''			#'''内的内容用于提示输入和输出是什么,可以省略

    :param r: 输入半径
    :return: 返回圆的面积
    '''
    s = PI * r * r
    print(s)
-------------
circle_area(r)	#调用函数

我们来试试调用函数:

import json
if __name__ == '__main__':		#学到这,我们得习惯模拟main函数的概念,在main中输入
    circle_area(5.7)
    circle_area(10)
------------------------
输出结果:
102.0186
314.0

这样一个函数就被我们定义完成了。

参数

在调用函数时,函数可以通过参数来接收信息。

定义函数时的参数有:必选参数、默认参数、可变参数、关键字参数等。下面让我们来介绍一下:

必选参数

又名位置参数,必须在调用函数的时候给定值,调用函数时必须按顺序提供,不多不少。比如计算x的n次方:

def power(x,n):
    p = 1
    while n > 0 :
        n = n - 1
        p = p * x
    return p

其中,x,n就是必须要输入的参数。定义函数可以输入多个必选参数。

默认参数

同样以计算x的n次方为例,假设我们只想计算不同x的二次方,按上述的方法需要重复输入n = 2、,太过复杂,不妨直接将n定死,即将它设置为默认参数:

def power(x,n = 2):
    p = 1
    while n > 0 :
        n = n - 1
        p = p * x
    return p

如此,我们只需要更改x的值,就可得到它的二次方值:

print(power(6))
------------------
输出结果:
36

注意:

  • 必选参数在前,默认参数在后,否则Python的解释器会报错
  • 函数有多个参数时,把变化大的参数放前面,变化小的参数放后面,变化小的参数就可以作为默认参数

可变参数

对于一些问题,我并不明确一开始要输入多少个参数,比如计算一组数据的和,我不确定要输入几个参数时,可以使用可变参数。

可变参数允许传入0个或任意个参数,可变参数在函数调用时自动组装为一个tuple。

表示形式:

*+名字,一般都是 *args(不强制),就是一个可变参数,数据存放在了元组里。

比如:计算一组数据的平方和:

def calc(*num_list):		#这样我们就可以输入多个数据
    print(num_list)
    summ = 0
    for i in num_list:
        summ += i ** 2
    print(summ)

调用:

calc(1,2,3,4,5,6,7,8,9)
------------
输出结果:
285

注意:

  • 可变参数在函数内部作为元组处理。
  • 可变参数必须位于所有位置参数之后。

关键字参数

可变参数允许传入0个或任意个参数,可变参数在函数调用时自动组装为一个tuple,而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。

表示形式:

**kwargs 关键字参数 一般传入时需要带入参数名称 以字典的形式接收

比如:将城市、工作、身高、体重和住址通过字典形式输出:

def personal_info(**kwargs):
    print(kwargs)

调用:

personal_info(city='hf', job='AI engineer', weigth=180, height=170, address="汤臣一品")
------------------------
输出结果:
{'city': 'hf', 'job': 'AI engineer', 'weigth': 180, 'height': 170, 'address': '汤臣一品'}

组合使用

函数参数的组合使用:必选参数、默认参数、可变参数、关键字参数

def params_all(a, b, c=0, *args,**kwargs):
    print(a, b, c, args, d, e, kwargs)
    pass	#占位符,还没想好函数如何定义时占位不报错

调用:

params_all(1, 2, 3, 4, 5, 6, f=9, h=10)
-------------------------
输出结果:
1 2 3 (4, 5, 6) {'f': 9, 'h': 10}

命名空间namespace

![命名空间.png

作用域.png
  • 局部 函数内部找变量
  • 全局 在整个代码之前去寻找
  • 内置 python内置的模块去寻找
  • 可以向上寻找,但不可以向下下沉寻找:即局部可以去全局、内建找,但是它们不能去局部找。

我们来看一个内置函数sum():

print(sum([1, 2, 3, 4, 5]))
----------------
输出结果:
15

对于上述sum()在寻找作用域时的过程:先在局部找(没有)-- 再去全局找(也没有)-- 最后在内置中找到了内置函数sum(),然后进行对应操作。那现在我们先定义一个sum变量:

sum = 10		#不是关键字,可以设置变量,但是最好避免这样命名,此处为示范
print(sum([1, 3, 4, 5]))

那么此时,sum还可以正常求和嘛?看看输出结果:

    print(sum([1, 3, 4, 5]))
TypeError: 'int' object is not callable

结果报错,是因为sum先在局部中寻找,找到了sum = 10表示整数型,找到了就用,但是此时的sum并没有求和功能。覆盖了内置模块中的sum函数,变成一个常量,没有具体的意义。

故而报错。

局部作用域

局部找到数据就使用局部作用域内的数据,比如:

#局部
def aaa():
    m = 10
    n = 20
    print(n, x, m)
    
调用:

n = 9
x = 11
aaa()
--------------
输出结果:
20 11 10		#可以向上找寻变量,先找到谁就先用谁

全局作用域

#局部
def aaa():
    m = 10
    n = 20
    print(n, x, m)
    
#输出一个m
print(m)		#没有m值输出,因为这在全局作用域,不能下沉到局部寻找

闭包函数

闭包(Closure)是函数式编程中的一个重要概念,它出现在支持嵌套函数的编程语言中,如Python、JavaScript等。闭包允许一个函数访问并操作函数外部的变量,即使该函数在其外部函数的作用域之外执行。

让我们看看一个闭包函数:

# 闭包函数
# outer 数据enclosing 闭包函数外的函数
def outer():
    o_count = 1
    print(o_count)
    # inner 属于局部作用域
    def inner():
        i_count = 2
        print(i_count,o_count)
    return inner

上述代码中,

def outer():
    o_count = 1
    print(o_count)
#我可以将print输出写成:print(o_count,i_count)吗?

很显然是不可以的,因为inner 属于局部作用域,outer无法下沉寻找。

总结

本篇介绍了:

  1. 如何自定义函数
  2. 自定义函数需要用到的参数:必选参数(调用时必须给值)、默认参数、可变参数、关键字参数
  3. 命名空间namespace:局部、全局、内置作用域以及闭包函数。作用域的寻找只能从低到高,不能向下下沉寻找。

标签:函数,自定义,作用域,sum,参数,print,def
From: https://blog.csdn.net/m0_74896766/article/details/140418435

相关文章

  • css 自定义属性
    CSS自定义属性(CustomProperties),也称为CSS变量,是CSS中一种能够保存和复用值的机制。它们与常规的CSS属性不同,因为它们可以在整个文档中定义一次,然后在需要的任何地方使用。定义和语法定义一个自定义属性使用两个连字符(--)开头,后面跟着属性名,类似于下面的示例::root{--......
  • js 一个函数有几种类型的属性
    在JavaScript中,函数对象可以拥有多种类型的属性。主要可以分为以下几类:实例属性(Instanceproperties):这些属性是在通过函数构造函数创建实例时绑定到实例上的属性。原型属性(Prototypeproperties):这些属性是绑定到函数对象的原型上的属性。实例可以通过原型链访问这些......
  • es5 js函数有哪几种继承方式
    在ES5(ECMAScript5)中,JavaScript函数有几种继承方式,主要是通过原型链实现的。以下是常见的几种继承方式:原型链继承(PrototypeInheritance):原理:通过将子类的原型对象设置为父类的实例来实现继承。特点:可以继承父类的实例方法和属性,但无法实现多继承。示例:functionParent(na......
  • 函数式编程的交响曲:探索LangChain对函数式编程特性的支持
    函数式编程的交响曲:探索LangChain对函数式编程特性的支持引言在现代软件开发中,函数式编程(FunctionalProgramming,FP)以其独特的优势,如无副作用、易于并行处理等,逐渐受到开发者的青睐。LangChain作为一个多语言编程工具链,其设计理念在于支持多种编程范式,包括函数式编程。......
  • 帝国CMS网站通过自定义扩展变量功能,用户可以自定义公共的程序使用变量,为用户扩展系统
    通过自定义扩展变量功能,用户可以自定义公共的程序使用变量,为用户扩展系统带来便利。比如可以增加像系统$public_r[newsurl]这样的变量,还比如扩展了某个系统模型,需要增加设置项都可以用扩展变量来实现...等等。 一、登录后台,单击“系统”菜单,选择“扩展变量”......
  • Java 异常艺术:自定义异常的魔力——解锁编程的新维度
    超越常规的错误管理在编程的宇宙中,错误和异常如同星云般存在,既神秘又充满挑战。Java的异常处理机制,尤其是自定义异常,为我们提供了驾驭这一领域的强大工具。本文将引领你深入自定义异常的奥秘,不仅从基础讲起,还将通过一系列详尽案例和扩展讨论,展现其在实际开发中的无限可能......
  • 对象的生存期 内存 深度拷贝 拷贝构造函数 笔记
    栈上的东西如何存在?栈是类似一种数据结构,像摞在桌子上的一堆书,要看中间的书需要把上面的书拿走作用域:形象成一本书,书内声明的变量作用域结束,要把这本书从书堆中拿出来作用域指针是什么:基本是个类是一个指针的包装器,在构造时用堆分配指针析构时删除指针,可以实现自动化new......
  • opencv—常用函数学习_“干货“_总
    同样内容将拆解为一份份,发在我个人博客中如http://t.csdnimg.cn/icOfX(非VIP文章),整理不易、感谢你的点赞收藏目录一、图像文件1.imread:读取图像文件2.imwrite:写入图像文件3.imshow:显示图像4.VideoCapture:捕获视频二、创建Mat1、创建Mat对象2、操作Mat对象三、矩......
  • 函数调用栈
    1、程序源代码:[xuanmiao@localhostPractice]$catmain.c#include<stdio.h>intplus(inta,intb){intc=a+b;returnc;}intmain(){inta=1,b=2;intc=0;c=plus(a,b);return0;}2、编译[xuanmiao@localhostPractice......
  • 深入解析C++中的特殊成员函数:构造函数、析构函数、拷贝构造函数与赋值操作符
    深入解析C++中的特殊成员函数:构造函数、析构函数、拷贝构造函数与赋值操作符在C++编程的浩瀚宇宙中,构造函数、析构函数、拷贝构造函数和赋值操作符是构成对象生命周期和行为的四大基石。它们各自扮演着不可或缺的角色,确保了对象从创建到销毁,从复制到赋值的整个过程既安全又......