函数的进阶

GD32F105RBT6 keil工程模板 创建GD32F105RBT6的keil初始基础工程,未来的所有外设驱动都是基于这个基础工程进行扩展。 阅读详情

本节主要内容:

1. 函数参数--动态传参

2. 名称空间, 局部名称空间, 全局名称空间, 作⽤用域, 加载顺序.

3. 函数的嵌套

4. gloabal, nonlocal关键字


一. 函数参数--动态传参

      之前我们说过了传参, 如果我们需要给⼀一个函数传参, 而参数又是不确定的. 或者我给一个 函数传很多参数, 我的形参就要写很多, 很麻烦, 怎么办呢. 我们可以考虑使用动态参数.

    形参的第三种: 动态参数

   动态参数分成两种:

         1. 动态接收位置参数

             首先我们先回顾⼀一下位置参数, 位置参数, 按照位置进⾏行行传参

def chi(quality_food, junk_food):

   print("我要吃", quality_food, junk_food)

chi("⼤大⽶米饭", "⼩小⽶米饭")    # "大米饭"传递给quality_food   "小米饭"传递给junk_food 按照位置传

       现在问题来了了. 我想吃任意的食物. 数量是任意的, 食物也是任意的. 这时我们就要用到 动态参数了. 在参数位置编写*表示接收任意内容

def chi(*food):

   print("我要吃", food) chi("⼤大⽶米饭", "⼩小⽶米饭")

结果:

我要吃 ('大米饭', '小米饭')    # 多个参数传递进去. 收到的内容是元组tuple
    动态接收参数的时候要注意: 动态参数必须在位置参数后面

def chi(*food, a, b):

   print("我要吃", food, a, b)

chi("大米饭", "小米饭", "黄⽠瓜", "茄子")

   这时程序运行会报错. 因为前面传递进去的所有位置参数都被*food接收了. a和b永远接收不到参数
Traceback (most recent call last):

 File "/Users/sylar/PycharmProjects/oldboy/fun.py", line 95, in <module>

   chi("⼤大⽶米饭", "⼩小⽶米饭", "⻩黄⽠瓜", "茄⼦子")

TypeError: chi() missing 2 required keyword-only arguments: 'a' and 'b'

   所以必须改写成以下代码:

def chi(*food, a, b):

   print("我要吃", food, a, b)

chi("大米饭", "小米饭", a="黄瓜", b="茄子")   # 必须用关键字参数来指定

   这个时候a和b就有值了, 但是这样写呢位置参数就不能用了了. 所以. 我们要先写位置参数, 然后再⽤用动态参数

def chi(a, b, *food):

   print("我要吃", a, b, food)

chi("⼤大⽶米饭", "⼩小⽶米饭", "馒头", "⾯面条")   # 前两个参数⽤用位置参数来接收, 后面的参数⽤用 动态参数接收
    那默认值参数呢?

def chi(a, b, c='馒头', *food):

   print(a, b, c, food)

chi("香蕉", "菠萝")  # 香蕉 菠萝 馒头 (). 默认值⽣生效

chi("⾹香蕉", "菠萝", "葫芦娃")  # ⾹香蕉 菠萝 葫芦娃 ()    默认值不生效

chi("⾹香蕉", "菠萝", "葫芦娃", "口罩")    # 香蕉 菠萝 葫芦娃 ('⼝口罩',) 默认值不生效

   我们发现默认值参数写在动态参数前⾯面. 默认值只有一种情况可能会生效. 
def chi(a, b, *food, c="娃哈哈"):

   print(a, b, food, c)

chi("⾹香蕉", "菠萝")  # ⾹香蕉 菠萝 () 娃哈哈   默认值生效

chi("⾹香蕉", "菠萝", "葫芦娃")  # ⾹香蕉 菠萝 ('葫芦娃',) 娃哈哈    默认值生效

chi("⾹香蕉", "菠萝", "葫芦娃", "口罩")    # ⾹香蕉 菠萝 ('葫芦娃', '口罩') 娃哈哈  默认值生效

   这个时候我们发现所有的默认值都生效了了. 这个时候如果不给出关键字传参. 那么你的默 认值是永远都生效的.

顺序: 位置参数, 动态参数*, 默认值参数


2. 动态接收关键字参数

   在python中可以动态的位置参数, 但是*这种情况只能接收位置参数无法接收关键字参数.
在python中使用**来接收动态关键字参数

def func(**kwargs):

   print(kwargs)

func(a=1, b=2, c=3)

func(a=1, b=2)

结果:

{'a': 1, 'b': 2, 'c': 3}

{'a': 1, 'b': 2}

   这个时候接收的是⼀一个dict

   顺序的问题, 在函数调用的时候, 如果先给出关键字参数, 则整个参数列表会报错.

def func(a, b, c, d):

   print(a, b, c, d)


# 关键字参数必须在位置参数后面, 否则参数会混乱

func(1, 2, c=3, 4)

   所以关键字参数必须在位置参数后面. 由于实参是这个顺序. 所以形参接收的时候也是这个顺序. 也就是说位置参数必须在关键字参数前面. 动态接收关键字参数也要在后面

   最终顺序(*):        位置参数 >  *args > 默认值参数 > **kwargs

       这四种参数可以任意的进行使用. 如果想接收所有的参数:

def func(*args, **kwargs):

   print(args, kwargs)

func("麻花藤","马晕",wtf="胡辣汤")

       动态参数的另一种传参方式:

def fun(*args):

   print(args)
lst = [1, 4, 7]

fun(lst[0], lst[1], lst[2])

fun(*lst)   # 可以使用*把一个列表按顺序打散

s = "臣妾做不不到"

fun(*s)     # 字符串也可以打散, (可迭代对象)

   在实参位置上给一个序列,列表,可迭代对象前面加个*表示把这个序列按顺序打散. 
    在形参的位置上的* 表示把接收到的参数组合成一个元组

    如果是⼀一个字典, 那么也可以打散. 不过需要用两个*

def fun(**kwargs):

   print(kwargs)

dic = {'a':1, 'b':2}

fun(**dic)

       函数的注释:

def chi(food, drink)

:    """    这⾥里里是函数的注释 , 先写一下当前这个函数是干什么的 , 比如我这个函数就是一个吃

   :param :param food: 参数 food 是什什么意思

   :param :param drink: 参数 drink 是什什么意思

   :return :return: 返回的是什么东东

   """

   print(food, drink)

   return "very good"


二. 命名空间

   在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了,  至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此⽽而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空 间也会随着函数执行完毕而被清空.

def fun():

   a = 10

   print(a)

fun()

print(a)    # a不存在了已经..

   我们给存放名字和值的关系的空间起一个名字叫: 命名空间. 我们的变量在存储的时候就 是存储在这片空间中的.

    命名空间分类:

        1. 全局命名空间--> 我们直接在py⽂文件中, 函数外声明的变量量都属于全局命名空间

       2. 局部命名空间--> 在函数中声明的变量会放在局部命名空间

       3. 内置命名空间--> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内 置命名空间
 加载顺序:

       1. 内置命名空间
        2. 全局命名空间

       3. 局部命名空间(函数被执行的时候)        

取值顺序:

       1. 局部命名空间     

       2. 全局命名空间      

       3. 内置命名空间

      局部作用域--->内嵌函数作用域--->全局作用域--->内嵌函数作用域(builtins)

a = 10

def func():

   a = 20

   print(a)
func()  # 20
    作用域:  作用域就是作用范围, 按照生效范围来看分为 全局作用域和局部作用域

   全局作用域: 包含内置命名空间和全局命名空间. 在整个⽂文件的任何位置都可以使用(遵循从上到下逐行执行).

  局部作用域: 在函数内部可以使用.

             作用域命名空间:

        1. 全局作用域:    全局命名空间 + 内置命名空间

       2. 局部作用域:    局部命名空间    我们可以通过globals()函数来查看全局作⽤用域中的内容,  也可以通过locals()来查看局部作用域中的变量量和函数信息

a = 10

def func():

   a = 40

   b = 20

   def abc():

       print("哈哈")

   print(a, b)     # 这里使用的是局部作用域

   print(globals())    # 打印全局作⽤用域中的内容

   print(locals())     # 打印局部作⽤用域中的内容

func()

   三. 函数的嵌套

1. 只要遇见了()就是函数的调用. 如果没有()就不是函数的调用

2. 函数的执行顺序
def fun1():

   print(111)   
def fun2():

   print(222)

   fun1()

  fun2()

print(111)

# 函数的嵌套

def fun2():

   print(222)

   def fun3():

       print(666)

   print(444)

   fun3()

   print(888)

print(33)

fun2()

print(555)


四. 关键字global和nonlocal

   首先我们写这样一个代码, 首先在全局声明一个变量, 然后再局部调用这个变量, 并改变这个变量的值

a = 100

def func():

   global a    # 加了个global表不再局部创建这个变量了. 而是直接使用全局的a

   a = 28

   print(a)

func()

print(a)  # 结果:28  28

   global表示. 不再使用局部作用域中的内容了. 而改用全局作用域中的变量

lst = ["麻花藤", "刘嘉玲", "詹姆斯"]

def func():

   lst.append("马云")    # 对于可变数据类型可以直接进行访问. 但是不能改地址. 说白了. 不能赋值

   print(lst)

func()

print(lst)


nonlocal 表示在局部作用域中, 调用父级命名空间中的变量.

a = 10

def func1():

   a = 20

   def func2():
        nonlocal a

       a = 30

       print(a)

   func2()

   print(a)
func1()

结果:

加了nonlocal

30

30

不加nonlocal

30

20
    再看, 如果嵌套了很多层, 会是一种什么效果:

a = 1

def fun_1():

   a = 2

   def fun_2():

       nonlocal a

       a = 3

       def fun_3():          

              a = 4            

               print(a)        

       print(a)        

       fun_3()        

       print(a)    

   print(a)    

   fun_2()    

   print(a)
print(a)

fun_1()

print(a)

结果:1 2 3 4 3 2 1
这样的程序如果能分析明白. 那么作用域, global, nonlocal就没问题了

做了一个3DTiles编辑器,支持3DTiles的预览和裁剪导出 3DTiles编辑器的功能极其简洁,核心就是3DTiles格式模型的预览和裁剪。为了演示方便,本文所使用的源数据为mipmap3d[1]网站所提供的无人机拍摄影像,并进行3DTiles构建。打开软件,输入的绝对路径之后,点击添加模型,就可以将模型加载进预览区。之后,点击裁剪模式按钮,默认会出现立方体裁剪框,可通过拖动句柄的方式去调整裁剪框的范围。同时,除了默认的盒体裁切模式外,还支持多边形裁切,点击多边形裁切后,可切换到顶视图,选择重绘多边形,可进行打点绘制。 阅读详情

相关推荐

BMC的风扇控制 (Fan speed control)

这篇文章是我刚开始做风扇功能的时候写的,因为那时候都找不到主管要我报告的内容,所以报告完就顺便整理一下,最近因为在修控制学,之后应该会再补一篇和控制学相关的内容 (如果有空的话) BMC的风扇控制算一个蛮重要的功能,那这个功能包含了"TACH"和"PWM"这两个常用讯号怎么解读,还有最常用的控制演算法"PID(closed loop)"和"Stepwise(openloop)",而另外的Error control ,因为每家做法不同,就不会在这边作介绍 ##实作程式码是来自Facebook的openBM

yeiris的博客 1万+

kylin raw度量 需要注意的东西

大约就是 1.避免数据倾斜 2.设置参数 3.将大的segment变成小的segment进行操作 4.raw度量 在cuboid的大小不能超过1M 不然就bufferoverflowexeption 说是说以后会进行优化,然并卵 5.raw度量不支持where条件查询 链接:http://kylin.apache.org/blog/2016/05/29/raw-measure

菜皮的默默倾诉 2189

Fluent UDF实战:除了速度入口,你的DEFINE_PROFILE宏还能搞定这些边界条件(温度、组分、壁面接触角全解析)

本文深入解析Fluent UDF中DEFINE_PROFILE宏在复杂边界条件中的高阶应用,涵盖温度场、组分浓度和壁面接触角等关键场景。通过实战代码示例,展示如何实现空间梯度温度场、动态组分控制和接触角动态调整,助力CFD工程师突破标准界面限制,提升仿真精度和效率。

weixin_28688385的博客 450

3-KYLIN订单例程

转:http://blog.itpub.net/30089851/viewspace-2122586/ 一.Hive订单数据仓库构建 1. 创建事实表并插入数据 DROP TABLE IF EXISTS default.fact_order ; create table default.fact_order (   time_key string,   product_ke

u013385925的专栏 434

华为OD机试真题 2026-9-2【查找幸运数】

华为OD机试真题 新系统【查找幸运数】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【查找幸运数】多语言题解。

qq_45776114的博客 500

软考中级-软件设计师 Python基础

软考中级-软件设计师 Python知识点整理

片言可决讼,半纸能缚龙 3643

kylin 官方案例learn_kylin手动创建测试

在上一篇文章中介绍了kylin相关的基本知识,这篇文章的主要目的是针对kylin初学者,进行一次详细的kylin案例介绍,这里,我们还是以官方给定的数据为例。说明,我用的是kylin2.1.0. 与kylin1.x 可能有不一样的地方。核心概念 事实表和维度表事实表(Fact Table)是指存储有事实记录的表,如系统日志、销售记录等;事实表的记录在不断地动态增长,所以它的体积通常远大于其他表。 维

chenguangchun1993的博客 4220

手把手教你学 MATLAB 实战训练(6.5):基础实战实例

MATLAB 是一款强大的数学软件,广泛应用于工程计算、信号处理、控制系统设计、图像处理等领域。学习 MATLAB 不仅可以提高你的编程技能,还能帮助你解决实际的数学和工程问题。下面我将通过几个实战训练实例来教你如何使用 MATLAB。

xiaoheshang_123的博客 367

Kylin性能调优记——业务技术两手抓

背景最近开始使用了新版本的Kylin,在此之前对于新版本的了解只是代码实现和一些简单的新功能测试,但是并没有导入实际场景的数据做分析和查询,线上Hadoop稳定之后,逐渐得将一些老需求往新的环境迁移,基于以前的调研,新版本(V2,版本为1.5.2)的Kylin提供了几个比较显著的功能和优化: 新的度量类型,包括TOPN、基于bitmap的精确distinct count和RAW。 自定义度量框架,用

Hello World 1万+

【EMC专题】为什么芯片规格书ESD性能中看不到MM(机器放电模型)

器件级ESD包括三种类型,HBM人体放电模型、MM机械放电模型和CDM元件充电模型。但在芯片规格书中为什么只见到HBM模型与CDM模型,却没有看到MM模型的数据?

一点硬件 450

高级电机控制场景实例:基于Simulink的永磁同步电机基于Luenberger观测器的弱磁控制仿真

本文基于Simulink实现表贴式永磁同步电机(SPMSM)的Luenberger观测器弱磁控制仿真,通过构建“观测-弱磁-控制”协同逻辑,突破传统矢量控制的基速限制。利用线性化模型设计观测器实时估计电流与磁链,结合电压极限约束动态注入负d轴电流,实现转速扩展至12000rpm(4倍基速),弱磁区电流THD低于3%,动态响应时间小于5ms,验证了高速运行下系统稳定性与鲁棒性。附完整建模步骤、MATLAB函数代码及性能分析,适用于电动汽车、机床等高速驱动场景,为高级电机控制提供可复现的技术范式。

amy_mhd的博客 32

OLAP 玩转KYLIN 步七 官方案列实战之创建Cube之设计度量

紧接上一节,我们继续来看Cube创建的又一关键点,设计度量。 进入度量添加界面,Kylin默认会为我们创建一个Count(1)的度量,避免不必要的麻烦,不要对其做修改或删除。如图: 点击上图中的+Measure便可以添加我们自己的度量。 Kylin支持的度量有:SUM、MIN、MAX、COUNT、COUNT DISTINCT、TOP_N、RAW等。选择需要的度量 类型,然后再选择适...

啊_汤哥的博客 2119

使用abagen工具箱获取基于脑区的基因表达矩阵

脑区模板定义了您感兴趣的脑区的空间位置。abagen提供了一些预定义的脑区模板,您可以选择使用,也可以使用自定义的脑区模板。它提供了一种简便的方式来获取基于脑区的基因表达矩阵。abagen需要使用Allen脑图谱数据来获取基因表达矩阵。您可以使用abagen内置的下载功能来获取这些数据。这就是使用abagen工具箱获取基于脑区的基因表达矩阵的详细步骤。通过按照上述步骤操作,您可以轻松获取并使用Allen脑图谱数据中的基因表达信息。一旦您加载了脑区模板,您可以使用abagen来获取基于脑区的基因表达矩阵。

web_bug407的博客 1326

诺,你们要的Python进阶来咯!【函数、类进阶必备】

目录 一、Python进阶初体验——内置函数 1、数据类型相关 2、数值计算相关 3、bool 值判断相关 4、IO 相关 5、元数据相关 6、help()函数 7、sorted()函数 8、range()函数 二、给代码安个家——函数进阶 1、位置参数 2、参数默认值 3、关键字参数 4、任意参数列表 5、多返回值 三、让你函数更好用——类进阶 1、类属性和类方法 (1)类属性的定义 (2)类方法的定义 2、静态方法 3、私有属性、方法 4、特殊方法 5、类的

累计发表博客60余万字,优快云 博客专家、Java 领域优质创作者、华为云享专家、阿里云专家博主。专注分享 Java 优质文章,毕设实战项目开发,全网粉丝10W+ 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Python函数进阶

函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形式 无参数,无返回值 无参数,有返回值 有参数,无返回值 有参数,有返回值 定义函数时,是否接收参数,或者是否返回结果,是根据 实际的功能需求 来决定的! 如果函数 内部处理的数据不确...

新海说 369

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

函数进阶版

必须保证带有默认值的缺省参数在参数列表末尾所以,以下定义是错误的!有时可能需要一个函数能够处理的参数个数是不确定的,这个时候,就可以使用多值参数python中有两种多值参数:参数名前增加一个可以接收元组参数名前增加两个可以接收字典一般在给多值参数命名时,习惯使用以下两个名字*args—— 存放元组参数,前面有一个**kwargs—— 存放字典参数,前面有两个args是arguments的缩写,有变量的含义kw是keyword的缩写,kwargs可以记忆键值对参数print(num)

weixin_58423196的博客 786

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

JavaScript高级 函数进阶篇

相同点:都可以改变函数内部this指向;区别点:(1)、call()和apply()会调用函数,并且改变函数内部this指向;(2)、call()和apply()传递的参数不一样,call()传递参数arg1 、arg2… ,apply()必须是数组形式[arg];(3)、bind()不会调用函数,可以改变函数内部this指向;主要应用场景:(1)、call()经常做继承;(2)、apply()经常跟数组有关系,比如借助于数学对象实现数组最大值最小值;

qq_57162921的博客 1385

函数进阶

函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形式 无参数,无返回值 无参数,有返回值 有参数,无返回值 有参数,有返回值 定义函数时,是否接收参数,或者是否返回结果,是根据 实际的功能需求 来决定的! 如果函数 内部处理的数据不确...

SAN的知识库 202

python函数进阶

1.函数的进阶 *的魔性用法 # *的魔性用法: (函数中) def func(*args,**kwargs): print(args) # (1, 2, 3,'太白', 'wusir', '景女神') print(kwargs) l1 = [1, 2, 3] l2 = ['太白', 'wusir', '景女神'] func(l1,l2) func(*l1,*l2) # ...

weixin_34124651的博客 206

python函数进阶及作业

​return a+b2.定义函数,接受三个参数:姓名、年龄、职业,然后打印出一个介绍信息,如“姓名:张三,年龄:25,职业:工程师”。print(f"姓名:{name},年龄:{age},职业{career}")a ( "张三", 25, "工程师")3.接收一个列表,返回这个列表的最大值 平均值 最小值4.输入一个包含若干整数的列表,输入列表的最大值,列如输入【1,2,3,4,6666】,输出6666。

annsksmd的博客 1051

C++函数进阶

函数进阶 using 指令尽量不要出现在头文件中 因为在预编译的过程中,所有引用该头文件的文件都会再次申明出现这条using指令 顶层const和底层const 由于指针本身是一个对象,所以指针所指向的对象是不是常量和指针变量本身是不是常量是两个问题: 顶层const是指指针本身是一个常量,申明一个常量指针可以通过以下方式: int a = 1; int *const var = &a; //此处报错,表达式必须是可修改的左值 var = 0; 底层const是指指针所指向的对象是一个常量

yp010425的博客 310

09Python函数进阶

函数根据以及,可以,一共有组合形式。

dotnethello的博客 939

函数进阶.

目标:掌握函数相关易错点 & 项目开发必备技能。 今日概要: - 参数的补充 - 函数名,函数名到底是什么? - 返回值和print,傻傻分不清楚。 - 函数的作用域

Blk628lxy的博客 1056

python函数基础及进阶

python函数的基础及进阶分享

qq_52758588的博客 1068

Python 函数 基础及其进阶

初学者Python入门,函数的基础及其进阶的基本语法和知识点

Yean666的博客 1095
上一篇: 函数的参数
下一篇: 迭代器
raw_recruit0302
博客等级 码龄8年 30粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值