Python在main中调用函数内嵌套函数的方法及列表处理技巧
本文详解Python中如何在外部调用函数内部定义的嵌套函数,通过返回内部函数引用实现灵活调用。同时探讨在函数内处理列表或矩阵时,如何避免修改原数据的问题,提供字典转列表及引入numpy库两种解决方案,确保原数据结构不受影响。
Python调用嵌套函数的基本方法
在Python编程中,通常无法直接在函数外部调用另一个函数内部定义的局部函数。然而,若业务逻辑确实需要这种调用方式,可以通过特定的技术手段实现。
首先看一种常规情况下的错误尝试。
def a():#第一层函数
def b():#第二层函数
print('打开文件B')
b()#第二层中的函数直接调用
执行上述代码后,系统会抛出异常。
Traceback (most recent call last): File "C:/Users/rog/Desktop/wenzhang.py", line 4, in <module> b() NameError: name 'b' is not defined
若必须使用内部函数,解决方法是在外层函数中返回内部函数的引用。这样,通过调用外层函数获取内部函数的句柄,即可在外部执行该内部函数。
def a():#第一层函数
def b():#第二层函数
print('打开文件B')
return(b)
s=a()#首先要调用一次a函数,将a函数的返回值给s,这里也就是b函数
s()
运行上述修正后的代码,输出如下。
打开文件B >>>
通过全局变量动态调用多个内部函数
如果需要在一个外层函数中根据条件调用多个不同的内部函数,可以通过全局变量配合返回值来实现。
具体做法是定义一个全局变量Position_number,在外层函数a()中声明使用全局变量。根据该变量的值,函数a()返回不同的内部函数引用。通过改变全局变量的值并重新调用a(),可以动态切换调用的内部函数。
Position_number=0
def a():#第一层函数
global Position_number
def b():#第二层函数
print('打开文件B')
def c():
print('打开文件C')
def d():
print('打开文件D')
if(Position_number==0):
return(b)
if(Position_number==1):
return(c)
if(Position_number==2):
return(d)
s=a() #首先要调用一次a函数,将a函数的返回值给s,这里也就是b函数
s() #运行b函数
Position_number=1 #改变Position_number,使a()的返回值改变成c函数
s=a() #将c函数赋给s
s() #运行c函数
Position_number=2 #改变Position_number,使a()的返回值改变成c函数
s=a() #将d函数赋给s
s() #运行d函数
执行上述逻辑后的输出结果如下。
打开文件B 打开文件C 打开文件D >>>
避免函数内修改影响原始列表的技巧
补充知识:Python中如何在函数内部处理数据而不影响原始列表。
这里以修改三阶矩阵为例进行说明。
在Python中,若尝试将列表作为类似C++的形参传入函数并期望其行为一致,这是不可行的。Python仅支持引用传递和值传递:传入基本类型时为值传递,传入列表或字典时为引用传递。
由于引用传递的特性,在函数内部对列表或字典进行修改,函数外部的原始数据也会随之改变。这有时被视为Python的一个不便之处。若希望在函数内处理矩阵或列表,同时保持外部原始数据不变,需要采取特殊措施。
经过多次测试,发现一种有效方法:利用字典值的不可变性和列表的可变性。在函数外部使用字典类型,传入函数后,将其转换为新的字典变量并进一步转换为列表类型。这样在函数内对列表进行任意修改,都不会影响原始的字典数据。
以下是一个在函数内部修改三阶矩阵且不影響外部数据的示例程序。
juzhen=((1,2,3),(4,5,6),(7,8,9))
def delju(juzhen):
print(juzhen)
a=list((juzhen))
for i in range(len(a)):
a[i]=list(a[i])
print(a)
for i in range(len(a)):
del a[i][0]
print(a)
delju(juzhen)
print(juzhen)
运行结果如下所示。
((1, 2, 3), (4, 5, 6), (7, 8, 9))
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[2, 3], [5, 6], [8, 9]]
((1, 2, 3), (4, 5, 6), (7, 8, 9))
>>>
从结果可以看出,传入函数的是一个二维元组(类似字典结构),在函数内部将其转换为二维列表,对列表进行操作后,外部的原始元组数据保持不变。
那么,是否可以在字典的每个值都是列表的情况下,传入函数并修改列表内的值呢?答案是否定的。因为即使字典的值是列表形式,在函数内修改这些列表,仍然会影响函数外部字典中的列表数据。
验证这一结论的程序如下。
juzhen=([1,2,3],[4,5,6],[7,8,9])
def delju(juzhen):
print(juzhen)
a=list((juzhen))
print(a)
for i in range(len(a)):
del a[i][0]
print(a)
delju(juzhen)
print(juzhen)
执行结果如下。
([1, 2, 3], [4, 5, 6], [7, 8, 9])
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[2, 3], [5, 6], [8, 9]]
([2, 3], [5, 6], [8, 9])
>>>
从结果可以看出,在函数内部修改后,函数外部的字典内的列表也被同时修改了。
这说明了如何利用字典机制来解决函数内处理列表时的副作用问题。
方法二:
此外,还有一种更简便的方法:直接引入numpy库(import numpy as np),利用numpy内置函数直接处理矩阵。这是官方推荐的操作方式,性能更好且代码更简洁。
以上关于Python在main中调用函数内函数以及处理列表副作用的方法就是全部内容,希望能对大家有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













