乐趣区

关于python:深入理解-Python-中的函数参数传递机制

在 Python 中,对于函数的参数传递,有两种次要的形式:传值和传援用。事实上,Python 的参数传递是一种“传对象援用”的形式。接下来的文章咱们将具体介绍 Python 的函数参数传递机制,这对了解 Python 编程语言的底层实现以及优化你的代码都十分有帮忙。

一、Python 中的变量和对象

在深刻了解参数传递之前,咱们首先须要了解 Python 中的变量和对象的概念。

在 Python 中,所有的数据都是对象,无论是数字、字符串还是自定义类型。而变量则是指向对象的援用。

x = 3
y = x

在这个例子中,xy 都是指向整数 3 这个对象的援用。咱们能够通过 id() 函数查看它们指向的对象的内存地址,验证这一点。

print(id(x))  # 输入:94832830448320
print(id(y))  # 输入:94832830448320

二、可变对象和不可变对象

在 Python 中,对象能够分为可变对象和不可变对象。例如,列表、字典和汇合是可变对象,而数字、字符串和元组是不可变对象。

对于不可变对象,咱们无奈扭转对象本身,然而能够扭转变量所指向的对象。

x = 3
print(id(x))  # 输入:94832830448320

x = 4
print(id(x))  # 输入:94832830448352

在这个例子中,咱们先是让变量 x 指向了整数 3,而后又让 x 指向了整数 4。咱们无奈扭转整数 3 本身,然而能够扭转 x 所指向的对象。

对于可变对象,咱们既能够扭转对象本身,也能够扭转变量所指向的对象。

x = [1, 2, 3]
print(id(x))  # 输入:139644486420232

x.append(4)
print(id(x))  # 输入:139644486420232

x = [1, 2, 3, 4, 5]
print(id(x))  # 输入:139644486437576

在这个例子中,咱们先是让变量 x 指向了一个列表 [1, 2, 3],而后咱们通过 append() 办法扭转了这个列表,使其变为了 [1, 2, 3, 4]。此时,x 所指向的对象并没有扭转,然而对象本身产生了变动。而后,咱们让 x 指向了一个新的列表 [1, 2, 3, 4, 5]。此时,x 所指向的对象扭转了。

了解可变对象和不可变对象的区别,对于咱们正确理解 Python 变量和函数的行为,以及编写正确、无效的代码都是十分重要的。

三、参数传递机制

在 Python 中,函数参数的传递遵循“传对象援用”的形式。对于可变对象和不可变对象,体现进去的成果相似传值和传援用。

1. 不可变对象的参数传递

当咱们将一个不可变对象作为参数传递给函数时,函数外部无奈扭转这个对象本身。函数如果对这个参数进行扭转,实际上是创立了一个新的对象。

def change(n):
    print(id(n))
    n = 1000
    print(id(n))

x = 3
print(id(x))
change(x)
print(x)

在这个例子中,函数 change() 试图扭转参数 n。然而因为 n 是一个不可变对象,所以函数外部其实创立了一个新的对象,而原来的对象并没有扭转。

2. 可变对象的参数传递

当咱们将一个可变对象作为参数传递给函数时,函数外部能够扭转这个对象本身。

def change(n):
    print(id(n))
    n.append(4)

x = [1, 2, 3]
print(id(x))
change(x)
print(x)

在这个例子中,函数 change() 扭转了参数 n。因为 n 是一个可变对象,所以函数外部的扭转影响到了原来的对象。

四、函数参数传递机制的理论利用

了解了 Python 的参数传递机制,有助于咱们编写出更好的代码。例如,如果咱们晓得一个函数外部会扭转传入的可变对象,咱们可能须要在传入参数之前先创立一个正本。

def change(n):
    n.append(4)

x = [1, 2, 3]
change(x[:])
print(x)

在这个例子中,咱们传入了 x 的正本,因而函数外部的扭转不会影响到 x

总的来说,Python 的函数参数传递机制遵循“传对象援用”的形式,了解这一点,能帮忙咱们更好的了解 Python 的工作原理,并编写出更有效率和可读性更强的代码。

五、匿名函数 lambda

Python 中的 lambda 是一个十分实用的匿名函数工具,它容许咱们疾速定义简略的函数。

# 应用 lambda 定义一个匿名函数
square = lambda x: x**2

print(square(5))  # 输入:25

在这个例子中,咱们应用 lambda 关键字定义了一个匿名函数,该函数接管一个参数 x 并返回 x 的平方。

1. lambda 的利用场景

尽管 lambda 函数性能无限(只能写在一行上,不能蕴含简单的逻辑),但在某些状况下,它的应用能够让代码更简洁。例如,当咱们须要传入一个小的、长期的函数作为其余函数的参数时,就能够应用 lambda。

# 应用 lambda 在列表排序中实现自定义排序规定
data = [{'name':'Alan', 'age':20}, {'name':'Lisa', 'age':18}, {'name':'Tom', 'age':22}]
data.sort(key=lambda x: x['age'])

print(data)
# 输入:[{'name': 'Lisa', 'age': 18}, {'name': 'Alan', 'age': 20}, {'name': 'Tom', 'age': 22}]

在这个例子中,咱们应用 lambda 函数作为 sort() 函数的 key 参数,来实现依据年龄的排序。

六、函数式编程工具

Python 提供了一些内建函数,用于反对函数式编程,如 map()filter()reduce() 等。这些函数能够用来对列表或其余可迭代对象进行操作,而无需编写循环。

1. map() 函数

map() 函数接管一个函数和一个可迭代对象作为参数,并将该函数利用于可迭代对象的每个元素,而后返回一个新的可迭代对象。

# 应用 map() 函数将列表中的每个元素平方
nums = [1, 2, 3, 4, 5]
squares = map(lambda x: x**2, nums)

print(list(squares))  # 输入:[1, 4, 9, 16, 25]

在这个例子中,咱们应用 map() 函数和一个 lambda 函数,将列表中的每个元素平方。

2. filter() 函数

filter() 函数接管一个函数和一个可迭代对象作为参数,并返回一个新的可迭代对象,该对象蕴含所有使该函数返回 True 的元素。

# 应用 filter() 函数筛选出列表中的偶数
nums = [1, 2, 3, 4, 5]
evens = filter(lambda x: x % 2 == 0, nums)

print(list(evens))  # 输入:[2, 4]

在这个例子中,咱们应用 filter() 函数和一个 lambda 函数,筛选出列表中的偶数。

理解和把握 Python 函数的这些个性,能够帮忙咱们编写出更加灵便、无效和简洁的代码。在将来的学习和工作中,咱们还将遇到更多对于函数的利用场景,如装璜器、生成器等等,这些都能够看作是 Python 函数个性的延长和利用。

七、高阶函数

在 Python 中,函数是第一类对象,这意味着咱们能够将函数作为参数传递给其余函数,也能够让函数返回另一个函数。这样的函数,咱们通常称之为高阶函数。高阶函数是函数式编程中的重要概念。

1. 函数作为参数

# 定义一个函数,承受另一个函数作为参数
def apply_func(func, x):
    return func(x)

# 定义一个函数,计算平方
def square(x):
    return x ** 2

print(apply_func(square, 5))  # 输入:25

在这个例子中,apply_func 是一个高阶函数,它接管另一个函数 square 作为参数。

2. 函数作为返回值

# 定义一个函数,返回另一个函数
def get_func(power):
    def power_func(x):
        return x ** power
    return power_func

square = get_func(2)
print(square(5))  # 输入:25

在这个例子中,get_func 是一个高阶函数,它返回一个新的函数 power_func

高阶函数为咱们的代码提供了很大的灵活性。例如,咱们能够依据须要动态创建和批改函数,也能够构建更加简单的函数逻辑。

八、总结

函数是 Python 编程的根底之一,把握 Python 函数的各种个性和用法对咱们的编程技能晋升十分重要。通过本篇文章,咱们对 Python 函数的基本概念和用法进行了回顾,并学习了 Python 中一些更高级的函数个性和用法,包含默认参数、可变参数、lambda 表达式、高阶函数等等。心愿这些内容对你有所帮忙,祝你在 Python 编程的路线上越走越远。

退出移动版