Python基础面试题38道精选

1、代码中要修改不可变数据会出现什么问题? 抛出什么异常?
答:代码不会正常运行,抛出 TypeError 异常。
2、a=1,b=2,不用中间变量交换 a 和 b 的值?
方法一:

a = a + b
b = a - b
a = a - b

方法二:

a = a^b
b = b^a
a = a^b

方法三:

a,b = b,a

3、print 调用 Python 中底层的什么方法?
答:print 方法默认调用 sys.stdout.write 方法,即往控制台打印字符串;
print在打印时会自动加个换行符,以下两行等价:

sys.stdout.write('hello'+'\n')
print 'hello'

4、下面这段代码的输出结果将是什么?请解释?

class Parent(object):
    x = 1
class Child1(Parent):
    pass
class Child2(Parent):
    pass
print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)

输出结果为:

1 1 1 #继承自父类的类属性 x,所以都一样,指向同一块内存地址。
1 2 1 #更改 Child1,Child1 的 x 指向了新的内存地址。
3 2 3 #更改 Parent,Parent 的 x 指向了新的内存地址。

5、简述你对 input()函数的理解?
答:在 Python3 中,input()获取用户输入,不论用户输入的是什么,获取到的都是字符串类型的。在 Python2 中有 raw_input()和 input(), raw_input()和 Python3 中的 input()作用是一样的,input()输入的是什么数据类型的,获取到的就是什么数据类型的。
6、阅读下面的代码,写出 A0,A1 至 An 的最终值。

A0 = dict(zip(('a', 'b', 'c', 'd', 'e'), (1, 2, 3, 4, 5)))
A1 = range(10)
A2 = [i for i in A1 if i in A0]
A3 = [A0[s] for s in A0]
A4 = [i for i in A1 if i in A3]
A5 = {i: i * i for i in A1}
A6 = [[i, i * i] for i in A1]

答:

A0 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
A1 = range(0,10)
#如输入print(list(A1)),可得到列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
A2 = []#i in A0查找的是字典中的key
A3 = [1, 2, 3, 4, 5]
A4 = [1, 2, 3, 4, 5]
A5 = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6 = [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], 
[7, 49], [8, 64], [9, 81]]

7、range 和 xrange 的区别?
答:在python2中,range返回的结果是一个列表,而xrange的结果是一个生成器,前者是直接开辟一块内存空间来保存列表,后者是边循环边使用,只有使用时才会开辟内存空间,所以当列表很长时,使用 xrange 性能要比 range 好.
在python3中,xrange被取消了,range返回的是一个可迭代对象,可以直接作用于for循环,要使用的时候也可以通过list()函数转化成list类型,关于可迭代对象、迭代器、生成器的区别可以查看以下链接
可迭代对象、迭代器和生成器的区别
8、考虑以下 Python 代码,如果运行结束,命令行中的运行结果是什么?

list1 = []
for i in range(10):
    list1.append({"num":i})
print(list1)

运行的结果为:

[{'num': 0}, {'num': 1}, {'num': 2}, {'num': 3}, {'num': 4}, {'num': 5}, {'num': 6}, {'num': 7}, {'num': 8}, {'num': 9}]

再考虑以下代码,运行结束后的结果是什么?

list2 = []
a = {"num":0}
for i in range(10):
    a["num"] = i
    list2.append(a)
print(list2)

运行的结果为:

[{'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}, {'num': 9}]

两段代码运行的结果为何不同?
答:字典是可变对象,在下方的 list2.append(a)的操作中是把字典 a 的引用传到列表 l ist2中,当后续操作修改 a[‘num’]的值的时候,list2中的值也会跟着改变,相当于浅拷贝。
9、以下 Python 程序的输出?

for i in range(5,0,-1):
    print(i)

答:

5
4
3
2
1

10、4G 内存怎么读取一个 5G 的数据?

方法一:
可以通过生成器,分多次读取,每次读取数量相对少的数据(比如 500MB)进行处理,处理结束后在读取后面的 500MB 的数据。
方法二:
可以通过 linux 命令 split 切割成小文件,然后再对数据进行处理,此方法效率比较高。可以按照行数切割,可以按照文件大小切割。
11、现在考虑有一个 jsonline 格式的文件 file.txt 大小约为 10K,之前处理文件的代码如下所示:

def get_lines():
    list1 = []
    with open("file.txt","rb") as f:
        for eachline in f:
            list1.append(eachline)
    return list1
if __name__ == '__main__':
    for e in get_lines():
    process(e) #处理每一行数据

现在要处理一个大小为 10G 的文件,但是内存只有 4G,如果在只修改 get_lines 函数而其他代码保持不变的情况下,应该如何实现?需要考虑的问题都有哪些?
答:内存只有 4G 无法一次性读入 10G 的文件,需要分批读入。分批读入数据要记录每次读入数据的位置。分批每次读入的数据也不能大小,太小就会在读取操作上花费过多时间。

def get_lines():
    l = []
    with open("file.txt","rb") as f:
        data = f.readlines(60000)
    l.append(data)
    yield l

Python yield 使用浅析
12、read、readline 和 readlines 的区别?
答: read:读取整个文件; readline:读取下一行,使用生成器方法; readlines:读取整个文件到一个迭代器以供我们遍历。
13、补充缺失的代码

def print_directory_contents(sPath):
	'''
	1/这个函数接收文件夹的名称作为输入参数
	2/返回该文件夹中文件的路径
	3/以及其包含文件夹中文件的路径
	'''

代码补充完整后如下:

def print_directory_contents(sPath):
    import os
    for sChild in os.listdir(sPath):
        sChildPath = os.path.join(sPath, sChild)
        if os.path.isdir(sChildPath):
            print_directory_contents(sChildPath)
        else:
            print(sChildPath)

14、在except 中return 后还会不会执行finally 中的代码?怎么抛出自定义异常?
答:会继续处理 finally 中的代码;用 raise 方法可以抛出自定义异常。
python3之异常处理try-except(finally)、raise,assert
15、介绍一下 except 的作用和用法?
答:
except: 捕获所有异常
except: <异常名>: 捕获指定异常
except:<异常名 1, 异常名 2> : 捕获异常 1或者异常 2
except:<异常名>,<数据>:捕获指定异常及其附加的数据
except:<异常名 1,异常名 2>:<数据>:捕获异常名 1 或者异常名 2,及附加的数据
python——异常except语句用法与引发异常
16、常用的 Python 标准库都有哪些?
答:
os 操作系统,time 时间,random 随机,pymysql 连接数据库,threading 线程,multiprocessing 进程,queue 队列。
第三方库:django 和 flask 也是第三方库,requests,virtualenv,selenium,scrapy,xadmin,celery,re,hashlib,md5。
常用的科学计算库(如 Numpy,Scipy,Pandas)。
17、赋值、浅拷贝和深拷贝的区别?
答:
①赋值:在 Python 中,对象的赋值就是简单的对象引用,如下所示:

a = [1,2,3,[-1]]
b = list1

在上述情况下,a 和 b 是一样的,他们指向同一片内存,b 不过是 a 的别名,是引用。
我们可以使用 b is a 去判断,返回 True,表明他们地址相同,内容相同,也可以使用 id()函数来查看两个列表的地址是否相同。赋值操作(包括对象作为参数、返回值)不会开辟新的内存空间,它只是复制了对象的引用。也就是说除了 b 这个名字之外,没有其他的内存开销。修改了 a,也就影响了 b,同理,修改了 b,也就影响了 a。
②浅拷贝(shallow copy)(不完全拷贝):
只适用于一维列表,使用浅拷贝的时候,会开辟一块新的内存区域,但是,若存在二维列表,由于列表存放的时候,只是存放的列表的地址,因此拷贝的列表中二维列表的地址是相同的。所以,当我们使用此方法操作二维列表的时候,会使源数据发生变化。比如:

a = [1,2,3,[-1]]
b = a.copy()

浅拷贝产生的列表 b 不再是列表 a 了,使用 is 判断可以发现他们不是同一个对象,使用 id 查看, 他们也不指向同一片内存空间。但是当我们使用 id(x) for x in a 和 id(x) for x in b 来查看 a 和 b 中元素的地址时,可以看到二者包含的元素的地址是相同的。在这种情况下,列表 a 和 b 是不同的对象,修改列表 b 理论上不会影响到列表 a。
但是要注意的是,浅拷贝之所以称之为浅拷贝,是它仅仅只拷贝了一层,在列表 a 中有一个嵌套的list,如果我们修改了它,情况就不一样了。
比如:a[3].append(‘java’)。查看列表 b,会发现列表 b 也发生了变化,这是因为,我们修改了嵌套的 list,修改外层元素,会修改它的引用,让它们指向别的位置,修改嵌套列表中的元素,列表的地址并未发生变化,指向的都是用一个位置。
③深拷贝(deep copy)(完全拷贝):
深拷贝使用的是copy模块中的deepcopy()函数
深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的时间和空间开销要高。同样的对列表 a,如果使用 b = copy.deepcopy(a),再修改列表 b 将不会影响到列表 a,即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何的关联。
18、拷贝的注意点?
对于非容器类型,如数字、字符,以及其他的“原子”类型,没有拷贝一说,产生的都是原对象的引用。
如果元组变量值都是原子类型对象,即使采用了深拷贝,也只能得到浅拷贝。
19、__init__和__new__的区别?
init 在对象创建后,对对象进行初始化。
new 是在对象创建之前创建一个对象,并将该对象返回给 init。
20、Python 里面如何生成随机数?
在 Python 中用于生成随机数的模块是 random,在使用前需要 import. 如下例子可以酌情列举:
random.random():生成一个 0-1 之间的随机浮点数;
random.uniform(a, b):
生 成 [a,b] 之 间 的 浮 点 数 ;
random.randint(a, b):生成[a,b]之间的整数;
random.randrange(a, b, step):在指定的集合[a,b)中,以 step 为基数随机取一个数;
random.choice(sequence):从特定序列中随机取一个元素,这里的序列可以是字符串,列表, 元组等。
21、输入某年某月某日,判断这一天是这一年的第几天?

import datetime
def dayofyear():
    year = input("请输入年份:")
    month = input("请输入月份:")
    day = input("请输入天:")
    date1 = datetime.date(year=int(year), month=int(month), day=int(day))
    date2 = datetime.date(year=int(year), month=1, day=1)
    return (date1 - date2).days + 1

扩展:
普通闰年:能被4整除但不能被100整除的年份为普通闰年。(如2004年就是闰年,1999年不是闰年);
世纪闰年:能被400整除的为世纪闰年。(如2000年是世纪闰年,1900年不是世纪闰年)。
22、打乱一个排好序的 list 对象 alist?

import random
random.shuffle(alist)

示例:

import random
list1 = [1,2,4,5,6]
list2 = random.shuffle(list1)
print(list1,list2)
[6, 1, 4, 2, 5] None

23、说明一下 os.path 和 sys.path 分别代表什么?
os.path 主要是用于对系统路径文件的操作。
sys.path 主要是对 Python 解释器的系统环境参数的操作(动态的改变 Python 解释器搜索路径)。
os.path以及sys.path模块简介
24、Python 中的 os 模块常见方法?
os模块简介
25、Python 的 sys 模块常用方法?
Python中os与sys两模块的区别
26、unittest 是什么?
在 Python 中,unittest 是 Python 中的单元测试框架。它拥有支持共享搭建、自动测试、在测试中暂停代码、将不同测试迭代成一组等功能。
27、模块和包是什么?
在 Python 中,模块是搭建程序的一种方式。每一个 Python 代码文件都是一个模块,并可以引用 其他的模块,比如对象和属性。
一个包含许多 Python 代码的文件夹是一个包。一个包可以包含模块和子文件夹。
28、Python 是强语言类型还是弱语言类型?
Python 是强类型的动态脚本语言。
强类型:不允许不同类型相加。
动态:不使用显示数据类型声明,且确定一个变量的类型是在第一次给它赋值的时候。
脚本语言:一般也是解释型语言,运行代码只需要一个解释器,不需要编译。
29、谈一下什么是解释性语言,什么是编译性语言?
计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。
编译性语言:编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。
解释性语言
解释则不同,解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译,比如python语言,专门有一个解释器能够直接执行python程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。
30、Python 中有日志吗?怎么使用?
有日志。Python 自带 logging 模块,调用 logging.basicConfig()方法,配置需要的日志等级和相应的参数, Python 解释器会按照配置的参数生成相应的日志。
31、Python 是如何进行类型转换的?
内建函数封装了各种转换函数,可以使用目标类型关键字强制类型转换,进制之间的转换可以用int(‘str’,base=’n’)将特定进制的字符串转换为十进制,再用相应的进制转换函数将十进制转换为目标进制。
可以使用内置函数直接转换的有:
list---->tuple tuple(list)
tuple---->list list(tuple)
32、Python2 与 Python3 的区别?
Python2.x与3​​.x版本区别
33、关于 Python 程序的运行方面,有什么手段能提升性能?

1、使用多进程,充分利用机器的多核性能
2、对于性能影响较大的部分代码,可以使用 C 或 C++编写
3、对于 IO 阻塞造成的性能影响,可以使用 IO 多路复用来解决
4、尽量使用 Python 的内建函数
5、尽量使用局部变量
34、Python 中的作用域?
作用域指的是变量的可用范围;
按作用域声明的位置不同可分为以下四类

局部作用域 函数体中声明的变量
嵌套作用域 嵌套函数体中外层函数体中声明的变量
全局作用域 py文件中声明的变量
内置作用域 Python提供的变量(函数)

当 Python 遇到一个变量的话它会按照这的顺序进行搜索:
局部作用域(Local)—>嵌套作用域(Enclosing locals)—>全局作用域(Global)—>内置作用域(Built-in)。
35、什么是Python?
Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。
1.Python 是一种编程语言,它有对象、模块、线程、异常处理和自动内存管理,可以加入其他语言的对比。
2.Python 是一种解释型语言,Python 在代码运行之前不需要解释。
3.Python 是动态类型语言,在声明变量时,不需要说明变量的类型。
4.Python 适合面向对象的编程,因为它支持通过组合与继承的方式定义类。在 Python 语言中,函数是第一类对象。
5.Python 代码编写快,但是运行速度比编译型语言通常要慢。
6.Python 用途广泛,常被用走"胶水语言",可帮助其他语言和组件改善运行状况。
7.使用 Python,程序员可以专注于算法和数据结构的设计,而不用处理底层的细节。
36、什么是 Python 自省?
简单的说就是使用一些机制实现自我检查,程序员可以使用这些机制查看各个对象或类型的信息。
python中的自省机制:
help():查看python自带的帮助文档信息;
dir():查看当前模块所有的类,对象,方法;
type(arg):返回对象的类型;
id(arg):返回对象的"唯一序号"等。
37、什么是Python的命名空间?
python的命名空间相当与是一个字典
键(key)是变量名,值(value)是变量名对应的对象,每个命名空间中不能定义相同的变量,符合字典的特性–不存在添加,存在修改,调用这个变量名就会自动进入命名空间寻找对应的对象
python的命名空间分为3个,他们互不影响,相互独立
第一个:每个函数内部都有属于自己的命名空间
第二个:每个模块都有自己的命名空间,存放模块内定义的变量,对象
第三个:python自带的内置命名空间,存放的是自带的属性…比如 print,int,str,class
命名空间的使用
当在一个函数内部调用一个变量时:
1.会先去函数内部的命名空间查找
2.再去模块的命名空间查找
3.最后去内置命名空间查找
4.如果都查找不到,就会报错 变量名 is not defined
38、你所遵循的代码规范是什么?请举例说明其要求?
Python 编码规范

你可能感兴趣的:(python)