25道Python经典面试题大全

1、什么是值传递、引用传递?

值传递是传递变量的值,不会改变函数外面变量的值。不可变对象(比如strings, tuples, 和numbers)用的是值传递。

引用传递是传递对象的地址,会改变对象本身的值,可变对象(比如list, dict, set)用的是引用传递。

2、什么是实参、形参?

形式传参:在定义函数时,函数名后面括号中的参数为“形式参数”,也称为形参。

实际参数:在调用函数时,函数名后面括号中的参数为“实际参数”,也称为实参。

def fun(a):  # 这里的a是形参   a = 2a = 1fun(a)  # 这里的a是实参

3、下面这个代码,最终输出的结果是多少?为什么?

a = 1def fun(a):   a = 2fun(a)print a

答案:

输出结果是1,因为a = 1,是Number类型的对象。Number属于不可变对象,这样实参的值传给形参的时候,会使用值传递,只会用实参的值来初始化形参的存储单元,也就是说实参和形参会是两个不同的存储单元,所以函数里面进行的赋值操作,不会改变函数外面变量的值。

4、什么是元类?

所有对象都是实例化或者调用类而得到的,python中一切都是对象,通过class关键字定义的类本质也是对象,对象又是通过调用类得到的,因此通过class关键字定义的类肯定也是调用了一个类得到的,这个类就是元类。type就是Python内置的元类。

5、在python中,什么是构造函数?

在创建类时,我们可以手动添加一个 __init__() 方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。

构造方法用于创建对象时使用,每当创建一个类的实例对象时,Python 解释器都会自动调用它。

6、类变量和实例变量

类变量:是可以在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。例如下例中,num_of_instance 就是类变量,用于跟踪存在着多少个Test 的实例。

实例变量:实例化之后,每个实例单独拥有的变量。

7、讲讲Python的静态方法、类方法、实例方法

class A(object):    # 实例方法   def foo(self,x):       print "executing foo(%s,%s)"%(self,x)        # 类方法   @classmethod   def class_foo(cls,x):       print "executing class_foo(%s,%s)"%(cls,x)        # 静态方法   @staticmethod   def static_foo(x):       print "executing static_foo(%s)"%x

实例方法:既可以获取构造函数定义的变量,也可以获取类的属性值,只能通过实例调用。

类方法:通过装饰器@calssmethod进行修饰。不能获取构造函数定义的变量,可以获取类的属性。有两种调用方式,a.类名.类方法名 b.实例化调用。它传递的是类而不是实例。

静态方法:通过装饰器@staticmethod进行修饰。不能获取构造函数定义的变量,也不可以获取类的属性。有两种调用方式,a.类名.静态方法名 b.实例化调用。

8、什么是Python自省?

在计算机编程领域里,自省是指程序运行时判断对象的类型的能力。它是Python的强项之一。

Python中比较常见的自省函数有:

type(),dir(),getattr(),hasattr(),isinstance(),通过这些函数,我们能够在程序运行时获知对象的类型,判断对象的属性。

9、列表推导式

推导式是python是一种独特的数据处理方式,Python中有三种推导式,分别是列表推导式、字典推导式和集合推导式。

列表推导式又叫列表生成式。

格式:[表达式 for 变量 in 列表 if 条件]

newlist = [i for i in range(10) if i > 3]

10、字典推导式

字典推导式在Python2.7中才加入的:

格式:{key: value for (key, value) in 字典}

listdemo = ['Google','Runoob', 'Taobao']newdict = {key:len(key) for key in listdemo}

11、Python中单下划线和双下划线

__foo__:是Python内部名字的约定,用来区别其他用户自定义的命名,以防冲突,例如__init__(),__del__(),__call__()这些特殊方法;

_foo:用来指定变量私有。不能用from module import * 导入,其他方面和公有一样访问;

__foo:解析器用_classname__foo来代替这个名字,用来区别和其他类相同的命名,它无法直接像公有成员一样随便访问,通过对象名._classname__foo来访问。

12、将列表生成式中[]改成()之后数据结构是否改变?

会改变,会从列表变为生成器。

通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量是有限的。并且创建一个包含百万元素的列表,会占用很大的内存空间。如果我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的,所以没有必要创建完整的列表。在Python中,我们可以采用生成器:边循环,边计算。

>>> L = [x*x for x in range(10)]>>> L[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g = (x*x for x in range(10))>>> g at 0x0000028F8B774200>

13、什么是Python迭代器iterator?

迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 可以通过iter()来创建迭代器,通过next()获取下一个元素。

>>> list=[1,2,3,4]# 创建迭代器对象>>> it = iter(list)    # 输出迭代器的下一个元素>>> print (next(it))   1>>> print (next(it))2

14、迭代器与列表的区别

(1)列表不论遍历多少次,表头位置始终是第一个元素;

(2)迭代器遍历结束后,不再指向原来的表头位置,而是为最后元素的下一个位置;

(3)列表可以通过内置函数iter()包装成迭代器。

15、什么是python生成器generator?

生成器就是一种一边使用一边计算的机制,使用第n个元素,则只需要生成前n元素。

如果我们使用其他可迭代对象处理庞大的数据时,会申请存储整个可迭代对象的内存,占用很大的内存空间,有的时候我们只需要访问前面几个元素,有的元素当前我们用不到,但它却一直占用这内存,非常浪费。

这时候就体现了生成器的优点了,它不是一次性把所有的结果都返回,而是当我们每读取一次,它会返回一个结果,当我们不读取时,它就是一个生成器表达式,几乎不占用内存。

16、生成器的工作原理

在调用生成器的过程中,遇到yield会暂停并保存运行信息,然后返回yield的值。

并在下一次执行next()方法时从当前位置继续运行。调用一个生成器函数,返回一个迭代器对象。

17、说说Python中迭代器和生成器的区别?

(1)生成器就是一种特殊的迭代器,能做到迭代器能做的所有事

(2)生成器是高效的,使用生成器表达式取代列表解析,会非常节省内存

(3)生成器除了创建和保持程序状态的自动生成,当发生器终结时,还会自动跑出StopIterration异常。

18、yeild 与 return的区别

相同点:都是返回函数执行的结果。

不同点:return 在返回结果后结束函数的运行,而yield 则是让函数变成一个生成器,生成器每次产生一个值(yield语句),函数被冻结,被唤醒后再产生一个值。

19、for循环的原理 

先调用可迭代对象的__iter__方法,返回一个迭代器,然后再对迭代器调用__next__方法,直到最后一个退出。

20、range()返回的是迭代器吗?

不是,Python3中,range() 返回的是一个可迭代对象,不是迭代器,也不是列表类型。

21、range对象是怎样占用内存的?

不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为仅仅需要存储start、stop和step,只有用到range对象时,才会去计算序列中的相关元素。

22、(i for i in range(5))  内存是一起开辟的吗?

不是一起开辟的,这是列表生成式,返回的是生成器,生成器是边循环边运行,不是一次性把所有的结果都返回。

23、python2和python3的range(100)的区别?

python2返回列表,python3返回迭代器对象,节省内存。

24、为什么使用* args,** kwargs?

当我们不确定将多少个参数传递给函数,或者我们想要将存储的列表或参数元组传递给函数时,我们使用* args。

当我们不知道将多少关键字参数传递给函数时使用** kwargs,或者它可以用于将字典的值作为关键字参数传递。

标识符args和kwargs是一个约定,你也可以使用* bob和** billy。

25、面向切面编程AOP和装饰器

装饰器的作用就是为已经存在的对象添加额外的功能。 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。

装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。

本次的内容大致的就介绍到这里拉,由于内容太多,只能简单介绍到这里,如有需要以上内容的完整版,大家可以私信我获取哦~~后台关注我后私信回复:【08】即可获取

你可能感兴趣的:(python,开发语言)