Python 常见面试题与参考答案详解
本文整理了 Python 开发中常见的面试问题,涵盖基础知识、进阶概念及实际应用。内容包含数据类型、字符串处理、函数定义、模块使用等核心知识点。
详细整理了 Python 开发中常见的 30 道面试题及其参考答案,内容覆盖基础数据类型、字符串处理、函数定义、模块使用、生成器与迭代器等核心概念。文章通过代码示例解释了切片、命名元组、随机数生成、正则匹配等具体用法,并对比了生成器与迭代器的区别,分析了 Python 语言的优缺点及参数传递机制。适合准备 Python 面试的开发者参考学习。

本文整理了 Python 开发中常见的面试问题,涵盖基础知识、进阶概念及实际应用。内容包含数据类型、字符串处理、函数定义、模块使用等核心知识点。
这是最基本的 Python 面试问题。Python 内置了多种标准数据类型:
1. Numbers(数字) 用于保存数值,包括整数、浮点数和复数。
>>> a = 7.0
>>> type(a)
<class 'float'>
2. Strings(字符串) 字符串是一个字符序列。我们用单引号或双引号来声明字符串。
>>> title = "Ayushi's Book"
>>> print(title)
Ayushi's Book
3. Lists(列表) 列表是一些值的有序集合,是可变的,我们用方括号声明列表。
>>> colors = ['red', 'green', 'blue']
>>> type(colors)
<class 'list'>
4. Tuples(元组) 元组和列表一样,也是一些值的有序集合,区别是元组是不可变的,意味着我们无法改变元组内的值。
>>> name = ('Ayushi', 'Sharma')
>>> name[0] = 'Avery'
TypeError: 'tuple' object does not support item assignment
5. Dictionary(字典) 字典是一种数据结构,含有键值对。我们用大括号声明字典。
>>> squares = {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
>>> type(squares)
<class 'dict'>
我们还可以使用字典推导式:
>>> squares = {x: x**2 for x in range(1, 6)}
>>> squares
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Docstring 是一种文档字符串,用于解释构造的作用。我们在函数、类或方法中将它放在首位来描述其作用。我们用三个单引号或双引号来声明 docstring。
>>> def sayhi():
"""用该函数打印 Hi"""
print("Hi")
>>> sayhi()
Hi
要想获取一个函数的 docstring,我们使用它的 __doc__ 属性。
>>> sayhi.__doc__
'\n\tThis function prints Hi\n\t'
和注释不同,docstring 在运行时会保留下来,可以通过 help() 函数查看。
PYTHONPATH 是 Python 中一个重要的环境变量,用于在导入模块的时候搜索路径。因此它必须包含 Python 源库目录以及含有 Python 源代码的目录。你可以手动设置 PYTHONPATH,但通常 Python 安装程序会把它呈现出来。
切片是 Python 中的一种方法,能让我们只检索列表、元素或字符串的一部分。在切片时,我们使用切片操作符 []。
>>> (1, 2, 3, 4, 5)[2:4]
(3, 4)
>>> [7, 6, 8, 5, 9][2:]
[8, 5, 9]
>>> 'Hello'[:-1]
'Hell'
Namedtuple 能让我们用名称/标签获取一个元组的元素,这里我们使用函数 namedtuple(),将其从 collections 模块中导入。
>>> from collections import namedtuple
>>> result = namedtuple('result', 'Physics Chemistry Maths')
>>> Ayushi = result(Physics=86, Chemistry=95, Maths=86)
>>> Ayushi.Chemistry
95
如上所示,它能让我们用对象 Ayushi 的 Chemistry 属性获取 Chemistry 中的符号。
和 C++ 等编程语言不同,Python 并没有多行注释,只有散列字符(#)。在符号 # 后的内容都被视作注释,解释器会自动将其忽略。
>>> # 注释行 1
>>> # 注释行 2
实际上你可以在代码中任何位置插入注释,用以解释代码逻辑。
如果字符串只含有数字字符,可以用函数 int() 将其转换为整数。
>>> int('227')
227
我们检查一下变量类型:
>>> type('227')
<class 'str'>
>>> type(int('227'))
<class 'int'>
我们用函数 input() 从用户那里获取输入。在 Python 2 中,我们还有另一个函数 raw_input()。
>>> a = input('Enter a number')
输入数字 7,但是如果你多加注意,会发现它以字符串形式获取输入。
>>> type(a)
<class 'str'>
将之乘以 2 能得到:
>>> a *= 2
>>> a
'77'
那么如果需要使用整数时呢?我们使用 int() 函数。
>>> a = int(input('Enter a number'))
>>> a *= 2
>>> a
14
首先,我们讨论一下什么是集合。集合就是一系列数据项的合集,不存在任何副本。另外,集合是无序的。
>>> myset = {1, 3, 2, 2}
>>> myset
{1, 2, 3}
这就意味着我们无法索引它。
>>> myset[0]
TypeError: 'set' object is not subscriptable
不过,集合是可变的。而不可变集合却不可变,这意味着我们无法改变它的值,从而也使其无法作为字典的键值。
>>> myset = frozenset([1, 3, 2, 2])
>>> myset
frozenset({1, 2, 3})
>>> type(myset)
<class 'frozenset'>
要想生成随机数,我们可以从 random 模块中导入函数 random()。
>>> from random import random
>>> random()
0.7931961644126482
关于内置函数 random 的帮助信息:
>>> help(random)
random(...) method of random.Random instance
random() -> x in the interval [0, 1).
这意味着 random() 会返回一个大于等于 0 且小于 1 的随机数。
我们还可以使用函数 randint(),它会用两个参数表示一个区间,返回该区间内的一个随机整数。
>>> from random import randint
>>> randint(2, 7)
6
最简单的方法就是用 capitalize() 方法。
>>> 'ayushi'.capitalize()
'Ayushi'
不过这也会让其它字母变为小写(如果是首字母后跟其他字母的情况)。
对于这个问题,我们可以使用 isalnum() 方法。
>>> 'Ayushi123'.isalnum()
True
>>> 'Ayushi123!'.isalnum()
False
我们还可以用其它一些方法:
>>> '123.3'.isdigit()
False
>>> '123'.isnumeric()
True
>>> 'ayushi'.islower()
True
>>> 'Ayushi'.isupper()
False
>>> 'Ayushi'.istitle()
True
>>> ' '.isspace()
True
>>> '123F'.isdecimal()
False
Python 中的连接就是将两个序列连在一起,我们使用 + 运算符完成。
>>> '32' + '32'
'3232'
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
注意元组连接时必须是元组:
>>> (2, 3) + (4,)
(2, 3, 4)
当我们想执行一系列语句时,我们可以为其赋予一个名字。我们来定义一个函数,让它取两个数返回一个更大的数。
>>> def greater(a, b):
return a if a > b else b
>>> greater(3, 3.5)
3.5
你可以自己创建函数,也可以使用 Python 的很多内置函数。
如果我们需要一个只有单一表达式的函数,我们可以匿名定义它。拉姆达表达式通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
假如我们想将上面 Q14 中的函数定义为拉姆达表达式,可以在解释器中输入如下代码:
>>> (lambda a, b: a if a > b else b)(3, 3.5)
3.5
当然,也有可能没有任何输入。
>>> (lambda: print("Hi"))()
Hi
在调用一个函数的过程中,直接或间接地调用了函数本身这个就叫递归。但为了避免出现死循环,必须要有一个结束条件。
>>> def facto(n):
if n == 1:
return 1
return n * facto(n - 1)
>>> facto(4)
24
生成器会生成一系列的值用于迭代,这样看它又是一种可迭代对象。它是在 for 循环的过程中不断计算出下一个元素,并在适当的条件结束 for 循环。
我们定义一个能逐个 yield 值的函数,然后用一个 for 循环来迭代它。
>>> def squares(n):
i = 1
while i <= n:
yield i**2
i += 1
>>> for i in squares(7):
print(i)
1
4
9
16
25
36
49
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。我们使用 iter() 函数创建迭代器。
>>> odds = iter([1, 3, 5, 7, 9])
每次想获取一个对象时,我们就调用 next() 函数。
>>> next(odds)
1
>>> next(odds)
3
现在我们再次调用它,会抛出 StopIteration 异常。这是因为它已经抵达需要迭代的值的尾部。
>>> next(odds)
StopIteration
在使用生成器时,我们创建一个函数;在使用迭代器时,我们使用内置函数 iter() 和 next()。
在生成器中,我们使用关键字 yield 来每次生成/返回一个对象。
生成器中有多少 yield 语句,你可以自定义。
每次 yield 暂停循环时,生成器会保存本地变量的状态。而迭代器并不会使用局部变量,它只需要一个可迭代对象进行迭代。
使用类可以实现你自己的迭代器,但无法实现生成器。
生成器运行速度快,语法简洁,更简单。 迭代器更能节约内存。
Python 有以下缺陷:
Python 新手可能对这个函数不是很熟悉,zip() 可以返回元组的迭代器。
>>> list(zip(['a', 'b', 'c'], [1, 2, 3]))
[('a', 1), ('b', 2), ('c', 3)]
在这里 zip() 函数对两个列表中的数据项进行了配对,并用它们创建了元组。
出现了这种问题时,我们可以按 Ctrl+C,这样可以打断执行程序。我们创建一个死循环来解释一下。
>>> def counterfunc(n):
while n == 7:
print(n)
>>> counterfunc(7)
7
...
KeyboardInterrupt
Python 使用按引用传递(pass-by-reference)将参数传递到函数中。如果你改变一个函数内的参数,会影响到函数的调用。这是 Python 的默认操作。
不过,如果我们传递字面参数,比如字符串、数字或元组,它们是不可变的,行为上类似于按值传递。对于可变对象(如列表、字典),修改会影响原对象。
我们可以使用函数/方法 getcwd(),从模块 os 中将其导入。
>>> import os
>>> os.getcwd()
'/path/to/current/directory'
我们还可以用 chdir() 修改当前工作目录。
>>> os.chdir('/path/to/new/directory')
>>> os.getcwd()
'/path/to/new/directory'
我们可以使用函数 search(),然后用 group() 获取输出。
>>> import re
>>> rhyme = re.search('.ake', 'I would make a cake, but I hate to bake')
>>> rhyme.group()
'make'
我们知道,函数 search() 会在第一次匹配时停止运行,这样我们就能得到第一个与'cake'押韵的字。
我们将内容读取为一个列表,然后在上面调用 reversed() 函数:
>>> with open('Today.txt', 'r') as f:
lines = f.readlines()
>>> for line in reversed(lines):
print(line.rstrip())
如果没有 rstrip(),我们会在输出中得到空行。
Tkinter 是一款很知名的 Python 库,用它我们可以制作图形用户界面。其支持不同的 GUI 工具和窗口构件,比如按钮、标签、文本框等等。
我们也能导入 Tkinter 模块。
>>> import tkinter
>>> top = tkinter.Tk()
这会为你创建一个新窗口,然后可以在窗口上添加各个构件。
虽然这两种文件均保存字节代码,但 .pyc 文件是 Python 文件的编译版本,它有平台无关的字节代码,因此我们可以在任何支持 .pyc 格式文件的平台上执行它。Python 会自动生成它以优化性能(加载时间,而非运行速度)。
Python 中创建包是比较方便的,只需要在当前目录建立一个文件夹,文件夹中包含一个 __init__.py 文件和若干个模块文件,其中 __init__.py 可以是一个空文件,但还是建议将包中所有需要导出的变量放到 __all__ 中,这样可以确保包的接口清晰明了,易于使用。
这个也比较简单,在我们想计算长度的字符串上调用函数 len() 即可。
>>> len('Ayushi Sharma')
13
以上涵盖了 Python 基础到进阶的常见面试考点。掌握这些知识点有助于应对大多数初级至中级 Python 开发岗位的面试。建议在实际项目中多加练习,巩固理解。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online