Python常见面试题的详解11
1. 函数调用参数的传递方式是值传递还是引用传递?
- 要点
在 Python 中,参数传递方式既不是纯粹的值传递,也不是纯粹的引用传递,而是 “对象引用传递”。本质上传递的是对象引用的副本,对于不可变对象,函数内修改参数不会影响原对象;对于可变对象,函数内修改参数可能会影响原对象。
python
# 不可变对象作为参数(类似值传递)
def modify_immutable(num):
num = num + 1
return num
a = 1
print(modify_immutable(a)) # 输出 2
print(a) # 输出 1,a 的值未改变
# 可变对象作为参数(类似引用传递)
def modify_mutable(lst):
lst.append(4)
return lst
my_list = [1, 2, 3]
print(modify_mutable(my_list)) # 输出 [1, 2, 3, 4]
print(my_list) # 输出 [1, 2, 3, 4],my_list 的值被改变
- 示例
在实际编程中,了解参数传递方式有助于避免意外修改数据。例如当需要保护可变对象不被函数修改时,可以传递其副本:
python
def modify_mutable_safely(lst):
new_lst = lst.copy()
new_lst.append(4)
return new_lst
my_list = [1, 2, 3]
print(modify_mutable_safely(my_list)) # 输出 [1, 2, 3, 4]
print(my_list) # 输出 [1, 2, 3],my_list 的值未改变
2. 如何理解缺省参数?
- 要点
缺省参数(默认参数)是在函数定义时为参数指定默认值。调用函数时若未提供该参数的值,则使用默认值。这提高了函数的灵活性,减少了代码重复。
python
def greet(name, message="Hello"):
print(f"{message}, {name}!")
greet("Alice") # 输出 "Hello, Alice!"
greet("Bob", "Hi") # 输出 "Hi, Bob!"
- 示例
默认参数必须放在非默认参数之后,且默认参数的值在函数定义时就被确定,而不是在调用时。若默认参数是可变对象,可能会出现意外结果:
python
def add_item(item, lst=[]):
lst.append(item)
return lst
print(add_item(1)) # 输出 [1]
print(add_item(2)) # 输出 [1, 2],而不是预期的 [2]
# 正确做法,使用 None 作为默认值
def add_item_safely(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
print(add_item_safely(1)) # 输出 [1]
print(add_item_safely(2)) # 输出 [2]
3. MySQL 怎么限制 IP 访问?
- 要点
可以通过 MySQL 的用户权限设置和服务器防火墙规则来限制 IP 访问,增强数据库的安全性。
python
import mysql.connector
# 假设已经在 MySQL 中创建了只允许特定 IP 访问的用户
try:
mydb = mysql.connector.connect(
host="localhost",
user="testuser",
password="your_password",
database="your_database"
)
print("Connected to MySQL!")
except mysql.connector.Error as err:
print(f"Error: {err}")
- 示例
在 MySQL 中,可以使用更复杂的权限设置,如限制用户对特定表、特定操作的访问:
sql
-- 只允许 192.168.1.100 的用户 testuser 对表 your_table 进行 SELECT 操作
GRANT SELECT ON your_database.your_table TO 'testuser'@'192.168.1.100' IDENTIFIED BY 'your_password';
FLUSH PRIVILEGES;
4. 什么是带参数的装饰器?
- 要点
带参数的装饰器是装饰器的扩展,允许装饰器接收额外参数。通常通过三层嵌套函数实现,外层函数接收装饰器参数,中层函数接收被装饰函数,内层函数实现具体功能。
python
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello() # 会输出三次 "Hello!"
- 示例
带参数的装饰器可用于更复杂的场景,如日志记录、性能监控等。例如根据不同参数记录不同级别的日志:
python
import logging
def log(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == 'info':
logging.info(f"Calling function {func.__name__}")
elif level == 'debug':
logging.debug(f"Calling function {func.__name__}")
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@log('info')
def my_function():
print("Function is running.")
my_function()
5. 为什么函数名字可以当做参数用?
- 要点
在 Python 中,函数是一等公民,可像其他数据类型一样赋值、传递和返回。这使得函数编程更加灵活,可实现高阶函数等功能。
python
def add(a, b):
return a + b
def apply(func, a, b):
return func(a, b)
result = apply(add, 3, 4)
print(result) # 输出 7
- 示例
函数作为参数可用于实现策略模式,根据不同的策略函数执行不同的操作:
python
def multiply(a, b):
return a * b
def subtract(a, b):
return a - b
def calculate(func, a, b):
return func(a, b)
print(calculate(add, 5, 3)) # 输出 8
print(calculate(multiply, 5, 3)) # 输出 15
print(calculate(subtract, 5, 3)) # 输出 2
6. 有如下一段代码,print c 会输出什么,为什么?
python
a = 10
b = 20
c = [a]
a = 15
print(c)
- 要点
列表 c
存储的是变量 a
的值,而不是变量 a
本身。当 a
的值改变时,不会影响 c
中已存储的值。上述代码输出 [10]
。因为 c = [a]
操作是将 a
的值 10
复制到列表 c
中,之后 a
重新赋值为 15
,对列表 c
没有影响。
- 示例
若要实现 c
随 a
的变化而变化,可以使用自定义类来封装 a
和 c
的关系:
python
class ValueTracker:
def __init__(self, value):
self.value = value
self.tracked_list = [self.value]
def update_value(self, new_value):
self.value = new_value
self.tracked_list[0] = self.value
tracker = ValueTracker(10)
c = tracker.tracked_list
print(c) # 输出 [10]
tracker.update_value(15)
print(c) # 输出 [15]
7. 什么是map 函数和 reduce 函数?
- 要点
-
map
函数:将一个函数应用到可迭代对象的每个元素上,返回一个迭代器。 -
reduce
函数(Python 3 中在functools
模块):对可迭代对象的元素进行累积操作。
python
# map 函数
numbers = [1, 2, 3, 4]
squared = map(lambda x: x ** 2, numbers)
print(list(squared)) # 输出 [1, 4, 9, 16]
# reduce 函数
from functools import reduce
sum_result = reduce(lambda x, y: x + y, numbers)
print(sum_result) # 输出 10
- 示例
map
函数可用于多个可迭代对象:
python
list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = map(lambda x, y: x + y, list1, list2)
print(list(result)) # 输出 [5, 7, 9]
# reduce 函数可用于自定义累积规则,如计算阶乘
def factorial(n):
return reduce(lambda x, y: x * y, range(1, n + 1))
print(factorial(5)) # 输出 120
8. 回调函数是如何通信的?
- 要点
回调函数是作为参数传递给另一个函数的函数,在特定事件或操作完成时被调用。通信方式分为同步回调和异步回调。
python
# 同步回调
def callback(result):
print(f"The result is: {result}")
def calculate(a, b, callback):
result = a + b
callback(result)
calculate(1, 2, callback) # 输出 "The result is: 3"
# 异步回调(使用 asyncio)
import asyncio
async def async_operation(callback):
await asyncio.sleep(1)
result = 10
callback(result)
def async_callback(result):
print(f"Async result: {result}")
async def main():
await async_operation(async_callback)
asyncio.run(main())
- 示例
回调函数可用于事件驱动编程,如 GUI 编程中处理按钮点击事件:
python
import tkinter as tk
def button_click_callback():
print("Button was clicked!")
root = tk.Tk()
button = tk.Button(root, text="Click me", command=button_click_callback)
button.pack()
root.mainloop()
9. 主要的内置数据类型都有哪些? print dir (‘a’) 的输出?
- 要点
Python 主要内置数据类型包括数字类型(整数、浮点数、复数)、序列类型(字符串、列表、元组、范围)、映射类型(字典)、集合类型(集合、冻结集合)、布尔类型和空类型。dir('a')
输出字符串对象的所有属性和方法列表。
python
# 查看内置数据类型示例
num = 10 # 整数
float_num = 3.14 # 浮点数
complex_num = 1 + 2j # 复数
string = "Hello" # 字符串
list_data = [1, 2, 3] # 列表
tuple_data = (1, 2, 3) # 元组
range_data = range(5) # 范围
dict_data = {'key': 'value'} # 字典
set_data = {1, 2, 3} # 集合
frozenset_data = frozenset([1, 2, 3]) # 冻结集合
bool_value = True # 布尔值
none_value = None # 空类型
# 查看字符串对象的属性和方法
print(dir('a'))
- 示例
了解这些内置数据类型的属性和方法有助于高效编程。例如字符串的 split
方法可用于分割字符串:
python
text = "Hello,World"
words = text.split(',')
print(words) # 输出 ['Hello', 'World']
10. 写出map (lambda x:x*x,[y for y in range (3)]) 的输出?
- 要点
在 Python 3 中,map
函数返回迭代器,需转换为列表等可迭代对象查看结果。
python
result = map(lambda x: x * x, [y for y in range(3)])
print(list(result)) # 输出 [0, 1, 4]
- 示例
可以结合 map
函数和其他函数实现更复杂的操作,如将列表中的字符串转换为整数并求和:
python
str_list = ['1', '2', '3']
int_list = map(int, str_list)
sum_result = sum(int_list)
print(sum_result) # 输出 6
友情提示:本文已经整理成文档,可以到如下链接免积分下载阅读
https://download.csdn.net/download/ylfhpy/90398083