Python面试题

1、Python的特点和优点?

可解释、开源、动态特性、简洁明了、面向对象(可开动碱面)

详细特点可查看:https://data-flair.training/blogs/python-tutorial/

2、深拷贝、浅拷贝和直接赋值的区别?

1)深拷贝,把一个对象复制给另外一个对象,

2)

import copy

a = [1, 2, 3, [4, 5]]
print(f"原数组a:{a}, a的地址:{id(a)}")
b = copy.deepcopy(a)
print(f"深拷贝b:{b}, b的地址:{id(b)}")
c = copy.copy(a)
print(f"浅拷贝c:{c}, c的地址:{id(c)}")
d = a
print(f"直赋值d:{d}, d的地址:{id(d)}")

print("
第一次修改 用=修改
")
a[0]=6
print(f"原数组a:{a}, a的地址:{id(a)}")
print(f"深拷贝b:{b}, b的地址:{id(b)}")
print(f"浅拷贝c:{c}, c的地址:{id(c)}")
print(f"直赋值d:{d}, d的地址:{id(d)}")


print("
第二次修改 内层元素添加append一个数
")
a[3].append(9)
print(f"原数组a:{a}, a的地址:{id(a)}")
print(f"深拷贝b:{b}, b的地址:{id(b)}")
print(f"浅拷贝c:{c}, c的地址:{id(c)}")
print(f"直赋值d:{d}, d的地址:{id(d)}")

print("
第三次修改 外层元素添加append一个数
")
a.append(10)
print(f"原数组a:{a}, a的地址:{id(a)}")
print(f"深拷贝b:{b}, b的地址:{id(b)}")
print(f"浅拷贝c:{c}, c的地址:{id(c)}")
print(f"直赋值d:{d}, d的地址:{id(d)}") 

结果:

"D:Program FilesPythonPytestProjectScriptspython.exe" C:/Users/CXM/PycharmProjects/untitled2/test.py
原数组a:[1, 2, 3, [4, 5]], a的地址:1952842345288
深拷贝b:[1, 2, 3, [4, 5]], b的地址:1952843082120
浅拷贝c:[1, 2, 3, [4, 5]], c的地址:1952843201736
直赋值d:[1, 2, 3, [4, 5]], d的地址:1952842345288

第一次修改 用=修改

原数组a:[6, 2, 3, [4, 5]], a的地址:1952842345288
深拷贝b:[1, 2, 3, [4, 5]], b的地址:1952843082120
浅拷贝c:[1, 2, 3, [4, 5]], c的地址:1952843201736
直赋值d:[6, 2, 3, [4, 5]], d的地址:1952842345288

第二次修改 内层元素添加append一个数

原数组a:[6, 2, 3, [4, 5, 9]], a的地址:1952842345288
深拷贝b:[1, 2, 3, [4, 5]], b的地址:1952843082120
浅拷贝c:[1, 2, 3, [4, 5, 9]], c的地址:1952843201736
直赋值d:[6, 2, 3, [4, 5, 9]], d的地址:1952842345288

第三次修改 外层元素添加append一个数

原数组a:[6, 2, 3, [4, 5, 9], 10], a的地址:1952842345288
深拷贝b:[1, 2, 3, [4, 5]], b的地址:1952843082120
浅拷贝c:[1, 2, 3, [4, 5, 9]], c的地址:1952843201736
直赋值d:[6, 2, 3, [4, 5, 9], 10], d的地址:1952842345288

Process finished with exit code 0

  

1.浅拷贝:外层添加元素时,浅拷贝不会随原列表变化而变化;内层添加元素时,浅拷贝才会变化。
2.深拷贝:无论原列表如何变化,深拷贝都保持不变。
3.直接赋值:赋值对象随着原列表一起变化。

  1. 列表和元组之间的区别是?
    1. 即list和tuple,列表里的元素可变、元组里的不可变,但是元组可合并
    2. 元组属于不可变(immutable)序列,一旦创建,不允许修改元组中元素的值,也无法为元组增加或删除元素。因此,元组没有提供append()、extend()和insert()等方法,无法向元组中添加元素;同样,元组也没有remove()和pop()方法,也不支持对元组元素进行del操作,不能从元组中删除元素。元组也支持切片操作,但是只能通过切片来访问元组中的元素,而不允许使用切片来修改元组中元素的值,也不支持使用切片操作来为元组增加或删除元素。从一定程度上讲,可以认为元组是轻量级的列表,或者“常量列表”。
    3. 习惯上元组多用于用于存储异构元素,异构元素即不同数据类型的元素,比如(ip,port)。 另一方面,列表用于存储异构元素,这些元素属于相同类型的元素,比如[int1,in2,in3]
    4. 列表有append()、extend()和insert()、remove()和pop()等方法
    5. 都是序列,都可以存储任何数据类型,可以通过索引访问,支持使用双向索引访问其中的元素、使用内置函数len()统计元素个数、使用运算符in测试是否包含某个元素、使用count()方法统计指定元素的出现次数和index()方法获取指定元素的索引。
t=(1,2) copy_t = tuple(t) print(t is copy_t)#True #元组无法复制。 原因是元组是不可变的。 如果运行tuple(tuple_name)将返回自己。
  1. 解释一下Python中的三元运算子
[on true] if [expression] else [on false] >>> a,b=2,3 >>> min=a if a<b else b >>> min
  1.  在Python中如何实现多线程?
    1. 一个线程就是一个轻量级进程,多线程能让我们一次执行多个线程。我们都知道,Python是多线程语言,其内置有多线程工具包。Python中的GIL(全局解释器锁)确保一次执行单个线程。一个线程保存GIL并在将其传递给下个线程之前执行一些操作,这会让我们产生并行运行的错觉。但实际上,只是线程在CPU上轮流运行。当然,所有的传递会增加程序执行的内存压力。
    2. (4条消息) Python多线程的原理与实现_daiyu__zz的博客-CSDN博客_python 多线程
  2. Python中的继承
    1. 当一个类继承自另一个类,它就被称为一个子类/派生类,继承自父类/基类/超类。它会继承/获取所有类成员(属性和方法)。继承能让我们重新使用代码,也能更容易的创建和维护应用。Python支持如下种类的继承:
      1. 单继承:一个类继承自单个基类
      2. 多继承:一个类继承自多个基类
      3. 多级继承:一个类继承自单个基类,后者则继承自另一个基类
      4. 分层继承:多个类继承自单个基类
  3. 什么是Flask?
    1. Flask是Python编写的一款轻量级Web应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2。Flask使用 BSD 授权。其中两个环境依赖是Werkzeug和jinja2,这意味着它不需要依赖外部库。正因如此,我们将其称为轻量级框架。Flask会话使用签名cookie让用户查看和修改会话内容。它会记录从一个请求到另一个请求的信息。不过,要想修改会话,用户必须有密钥Flask.secret_key。
    2. Flask还有很强的定制性。除了Flask,还有django、Web2py等等。其中Django是目前Python的框架中使用度最高的。
  1. 在Python中是如何管理内存的?
    1. Python有一个私有堆空间来保存所有的对象和数据结构。作为开发者,我们无法访问它,是解释器在管理它。但是有了核心API后,我们可以访问一些工具。Python内存管理器控制内存分配。内置垃圾回收器会回收使用所有的未使用内存,所以使其适用于堆空间。
    2. 从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制
      1. 对象的引用计数机制:Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。
        1. 引用计数增加的情况:①一个对象分配一个新名称,②将其放入一个容器中(如列表、元组或字典)
        2. 引用计数减少的情况:①使用del语句对对象别名显示的销毁,②引用超出作用域或被重新赋值
        3. sys.getrefcount( )函数可以获得对象的当前引用计数
        4. 多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。
      2. 垃圾回收
        1. 当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。
        2. 当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。
      3. 内存池机制:Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
        1. Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
        2. Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。
        3. 对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
  2. 解释Python中的help()和dir()函数
    1. Help()函数是一个内置函数,用于查看函数或模块用途的详细说明:
>>> import copy >>> help(copy.copy) #运行结果: Help on function copy in module copy: copy(x) Shallow copy operation on arbitrary Python objects. See the module’s __doc__ string for more info.
    1. Dir()函数也是Python内置函数,dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
>>> dir(copy.copy) [‘__annotations__’, ‘__call__’, ‘__class__’, ‘__closure__’, ‘__code__’, ‘__defaults__’, ‘__delattr__’, ‘__dict__’, ‘__dir__’, ‘__doc__’, ‘__eq__’, ‘__format__’, ‘__ge__’, ‘__get__’, ‘__getattribute__’, ‘__globals__’, ‘__gt__’, ‘__hash__’, ‘__init__’, ‘__init_subclass__’, ‘__kwdefaults__’, ‘__le__’, ‘__lt__’, ‘__module__’, ‘__name__’, ‘__ne__’, ‘__new__’, ‘__qualname__’, ‘__reduce__’, ‘__reduce_ex__’, ‘__repr__’, ‘__setattr__’, ‘__sizeof__’, ‘__str__’, ‘__subclasshook__’]
  1. 当退出Python时,是否释放全部内存?
    1. 答案是No。循环引用其它对象或引用自全局命名空间的对象的模块,在Python退出时并非完全释放。且也不会释放对C库保留的内存部分
  2. 什么是猴子补丁?
    1. 在运行期间动态修改一个类或模块
    2. 在运行时替换方法、属性等
  1. 在不修改第三方代码的情况下增加原来不支持的功能
  2. 在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加
这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分,这些被称作是“杂牌军补丁(guerilla patch)”,后来guerilla就渐渐的写成了gorllia((猩猩),再后来就写了monkey(猴子),所以猴子补丁的叫法是这么莫名其妙的得来的。
class A: def func(self): print("Hi") def monkey(self): print "Hi, monkey" m.A.func = monkey a = m.A() a.func() #运行结果 Hi, Monkey
  1. Python中的字典是什么?
    1. 字典是C++和Java等编程语言中所没有的东西,它具有键值对。字典是不可变的
  2. 请解释使用*args和**kwargs的含义
    1. 当我们不知道向函数传递多少参数时,比如我们向传递一个列表或元组,我们就使用*args
    2.  *args 用来将参数打包成tuple给函数体调用
>>> def func(*args): for i in args: print(i) >>> func(3,2,1,4,7) #运行结果 3 2 1 4 7
    1. 在我们不知道该传递多少关键字参数时,使用**kwargs来收集关键字参数。
    2. **kwargs 打包关键字参数成dict给函数体调用
>>> def func(**kwargs): for i in kwargs: print(i,kwargs[i]) >>> func(a=1,b=2,c=7) #运行结果 a.1 b.2 c.7 注意点:参数arg、*args、**kwargs三个参数的位置必须是一定的。 必须是(arg,*args,**kwargs)这个顺序,否则程序会报错。 def function(arg,*args,**kwargs): print(arg,args,kwargs) function(6,7,8,9,a=1, b=2, c=3)
  1. 什么是负索引?
    1. 负索引和正索引不同,它是从右边开始检索。列表的负查询,切片等
  2. 如何以就地操作方式打乱一个列表的元素?
    1. 从random模块中导入shuffle()函数。
>>> from random import shuffle >>> shuffle(mylist) >>> mylis #运行结果 [3, 4, 8, 0, 5, 7, 6, 2, 1]
  1.  解释Python中的join()和split()函数
    1. Join()能让我们将指定字符添加至字符串中。
>>> ','.join('12345') #运行结果 ‘1,2,3,4,5’
    1. Split()能让我们用指定字符分割字符串。
>>> '1,2,3,4,5'.split(',') #运行结果 [‘1’, ‘2’, ‘3’, ‘4’, ‘5’]
  1. Python区分大小写吗?
    1. 区分
  2. Python中的标识符长度能有多长?
    1. 可以任意长度,但要符合要求。只能以下划线或者 A-Z/a-z 中的字母开头
    2.  其余部分可以使用 A-Z/a-z/0-9
    3. 区分大小写
    4. 关键字不能作为标识符
  1. 怎么移除一个字符串中的前导空格?
    1. 字符串中的前导空格就是出现在字符串中第一个非空格字符前的空格。我们使用方法Istrip()可以将它从字符串中移除。
    2. 如果我们想去除后缀空格,就用rstrip()方法。
>>> ' Erain '.lstrip() >>> ' Erain '.rstrip() #运行结果 ‘Ayushi’
  1. 怎样将字符串转换为小写?
>>> 'Erain'.lower() #转换为小写 'erain' >>> 'Erain'.upper() #转换为大写 'ERAIN' >>>'@Erain'.isupper() #判断使用isupper()和islower()方法检查字符春是否全为大写或小写。 false >>>'@Erain'.islower() #@和$这样的字符既满足大写也满足小写。 false
  1. Python中的pass语句是什么?
    1. 在用Python写代码时,有时可能还没想好函数怎么写,只写了函数声明,但为了保证语法正确,必须输入一些东西,在这种情况下,我们会使用pass语句。
    2. break语句能让我们跳出循环。
    3. continue语句能让我们跳过这次循环,直接跳到下个循环。
#pass用法 >>> def func(*args): pass #break用法 >>> for i in range(7): if i==3: break print(i) #运行结果 0 1 2 #continue用法 >>> for i in range(4): if i==3: continue print(i) #运行结果 0 1 2 4
----------------------------------------------以上为基础中的基础----------------------------------------------
  1. Python中的闭包是什么?
    1. 当一个嵌套函数在其外部区域引用了一个值时,该嵌套函数就是一个闭包。其意义就是会记录这个值。
    2. 如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数,在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
    3. 一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
#闭包函数的实例 # outer是外部函数 a和b都是外函数的临时变量 def outer( a ): b = 10 # inner是内函数 def inner(): #在内函数中 用到了外函数的临时变量 print(a+b) # 外函数的返回值是内函数的引用 return inner if __name__ == '__main__': # 在这里我们调用外函数传入参数5 #此时外函数两个临时变量 a是5 b是10 ,并创建了内函数,然后把内函数的引用返回存给了demo # 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数 demo = outer(5) # 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量 # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数 demo() # 15 demo2 = outer(7) demo2()#17
  1. 装饰器就是在闭包的基础上,传递一个函数,覆盖了原函数的入口,以后在调用这个函数的时候,可以额外多实现一些功能
    1. https://www.jb51.net/article/86383.htm
  2. 解释一下Python中的//,%和 ** 运算符
#//运算符执行地板除法(向下取整除),它会返回整除结果的整数部分。 >>> 7//2 #3 #**执行取幂运算。a**b会返回a的b次方 >>> 2**10 #1024 #%执行取模运算,返回除法的余数 >>> 13%7 #6 >>> 3.5%1.5 #0.5
  1. 在Python中有多少种运算符?解释一下算数运算符。
    1. 有7种运算符:算术运算符(+-*/)、关系运算符(><=)、赋值运算符、逻辑运算符(=+=-=)、位运算符、成员运算符(in)、身份运算符(is)。
    2. 其中算数运算符有:加减乘除,取模%,取幂**,取整除//
  2. 解释一下Python中的关系运算符。
    1. 关系运算符用来比较两个值
#小于号(<),如果左边的值较小,则返回True。 >>> 'hi'<'Hi' #False #大于号(>),如果左边的值较大,则返回True。 >>>1.1+1.2>3.3 #False #小于等于号(<=),如果左边的值小于或等于右边的值,则返回Ture。 >>> 3.0<=3 #true #大于等于号(>=),如果左边的值大于或等于右边的值,则返回True。 >>> True>=False #True #等于号(==),如果符号两边的值相等,则返回True。 >>> {1,3,2,2}=={1,2,3} #True #不等于号(!=),如果符号两边的值不相等,则返回True。 >>> True!=0.1 #True
  1. 解释一下Python中的赋值运算符
>>> a=7 >>> a+=1 #8 >>> a-=1 #7 >>> a*=2 #14 >>> a/=2 #7.0 >>> a**=2 #49 >>> a//=3 #整除,16.0 >>> a%=4 #取余,0.0
  1. 解释一下Python中的逻辑运算符
    1. Python中有3个逻辑运算符,有优先级大到小:or,and,not
False and True #False 7<7 or True #True not 2==2 #False
  1. 解释一下Python中的成员运算符
    1. 通过成员运算符‘in’和‘not in’,我们可以确认一个值是否是另一个值的成员
'ra' in 'Erain' #True 're' not in 'Erain' #True
  1. 解释一下Python中的身份运算符
    1. 通过身份运算符‘is’和‘is not’,我们可以确认两个值是否相同。
10 is '10' #False True is not False #True
  1. Python中的位运算符
    1. 该运算符按二进制位对值进行操作。
#与(&),按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 >>> 0b110 & 0b010 2 #或(|),按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 >>> 3|2 3 #异或(^),按位异或运算符:当两对应的二进位相异时,结果为1 >>> 3^2 1 #取反(~),按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 >>> ~2 -3 #左位移(<<),运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0 >>> 1<<2 4 #右位移(>>),把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 >>> 4>>2
  1. 在Python中如何使用多进制数字?
    1. 除十进制外还可以使用二进制、八进制和十六进制。
#二进制数字由0和1组成,我们使用 0b 或 0B 前缀表示二进制数。 >>> int(0b1010) #10 #使用bin()函数将一个数字转换为它的二进制形式。 >>> bin(0xf) #‘0b1111’ #八进制数由数字 0-7 组成,用前缀 0o 或 0O 表示 8 进制数。 >>> oct(8) #‘0o10’ #十六进数由数字 0-15 组成,用前缀 0x 或者 0X 表示 16 进制数。 >>> hex(16) #‘0x10’ >>> hex(15) #‘0xf’
  1. 怎样获取字典中所有键的列表?
#使用 keys() 获取字典中的所有键 >>> mydict={'a':1,'b':2,'c':3,'e':5} >>> mydict.keys() dict_keys(['a', 'b', 'c', 'e'])
  1. 为何不建议以下划线作为标识符的开头
    1. 因为Python并没有私有变量的概念,所以约定俗成以下划线为开头来声明一个变量为私有。所以如果你不想让变量私有,就不要使用下划线开头。
  2. 怎样声明多个变量并赋值?
>>> a,b,c=3,4,5 #This assigns 3, 4, and 5 to a, b, and c respectively >>> a=b=c=3 #This assigns 3 to a, b, and c
  1. 元组的解封装是什么?
#封装 mytuple=3,4,5 mytuple (3, 4, 5) #解封 >>> x,y,z=mytuple >>> x+y+z 12
  1. xrange 和 range 的区别?
    1. xrange 是在 Python2 中的用法,Python3 中只有 range xrange 用法与 range 完全相同,所不同的是生成的不是一个 list 对象,而是一个生成器。
  2. Python里面如何实现tuple和list的转换?
    1. 直接使用tuple和list函数就行了,type()可以判断对象的类型
  3. 什么是lambda函数?它有什么好处?
    1. lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数,首要用途是指点短小的回调函数
lambda [arguments]:expression >>> a=lambdax,y:x+y >>> a(3,11)
  1. 介绍一下except的用法和作用?
    1. try…except…except…[else…][finally…]
    2. 执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行,如果存在finally语句,最后总是会执行。
  2. 介绍一下Python下range()函数的用法?
    1. 列出一组数据,经常用在for in range()循环中
  3. Python里面match()和search()的区别?
    1. re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。
    2. re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。
>>>print(re.match(‘super’, ‘superstition’).span()) (0, 5) >>>print(re.match(‘super’, ‘insuperable’)) None >>>print(re.search(‘super’, ‘superstition’).span()) (0, 5) >>>print(re.search(‘super’, ‘insuperable’).span()) (2, 7)
  1. 贪婪匹配(匹配优先)和非贪婪匹配(忽略优先)的区别
    1. (.*)是贪婪匹配,意思是尽可能多的取匹配符合条件的数据
    2. (.*?)是非贪婪匹配,意思是尽可能少的匹配符合条件的数据
#以网页标签的形式,比较容易理解 s="<a>哈哈</a><a>嘿嘿</a><a>哦豁</a>" import re res1=re.findall("<a>(.*)</a>",s) print(res1) res2=re.findall("<a>(.*?)</a>",s) print(res2)
  1. Python里面如何生成随机数?
    1. random模块
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):从特定序列中随机取一个元素,这里的序列可以是字符串,列表,元组等。
  1. 如何在一个function里面设置一个全局的变量?
#解决方法是在function的开始插入一个global声明: def hahah(): global a a=3 hahah() print(a)
  1. 列出5个python标准库
    1. os:提供了不少与操作系统相关联的函数
    2. sys: 通常用于命令行参数
    3. re: 正则匹配
    4. math: 数学运算
    5. datetime:处理日期时间
  2. 字典如何删除键和合并两个字典
dic={"name":"Erain","age":20,"face":"handsome"} print(dic) #{'name': 'Erain', 'age': 20, 'face': 'handsome'} #删除字典中的字段 del dic["age"] print(dic) #{'name': 'Erain', 'face': 'handsome'} dic2={"age":20} #合并字典 dic.update(dic2) print(dic) #{'name': 'Erain', 'face': 'handsome', 'age': 20}
  1. python的GIL
    1. GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
    2. 多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大
  2. python2和python3的range(100)的区别
    1. python2返回列表,python3返回迭代器,节约内存
  3. 简述面向对象中__new__和__init__区别
    1. __init__是初始化方法,创建对象后,就立刻被默认调用了,可接收参数
    2. __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
    3. __new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
    4. __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例
    5. 如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,;那么实际创建返回的就是其他类的实例,其实就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。
  4. 避免转义给字符串加哪个字母表示原始字符串?
    1. r , 表示需要原始字符串,不转义特殊字符
print r' '
  1. python中断言方法举例
    1. assert()方法,断言成功,则程序继续执行,断言失败,则程序报错
assert True     # 条件为 true 正常执行 assert False    # 条件为 false 触发异常 Traceback (most recent call last):   File "<stdin>", line 1, in <module> AssertionError
  1. python之排序(sort/sorted)
    1. L.sort() 函数只适用于列表排序,而sorted()函数适用于任意可以迭代的对象排序
    2. L.sort() 函数排序会改变原有的待排序列表,而sorted()函数则不会改变。所以在使用列表进行排序时,需要考虑是否需要保存原列表,如果无需保存原列表,则优先使用L.sort() 节省内存空间,提高效率。
    3. 两个函数通过定义 key 和 cmp 都可以完成排序,但是 key 的效率要远远高于 cmp,所以要优先使用 key 。
    4. python3没有cmp,用functools.cmp_to_key()装饰一下
A = [3,6,1,5,4,2] A.sort() # [1, 2, 3, 4, 5, 6],返回的是列表 student = [['Tom', 'A', 20], ['Jack', 'C', 18], ['Andy', 'B', 11]] student.sort(key=lambda student: student[2]) #[['Andy', 'B', 11], ['Jack', 'C', 18], ['Tom', 'A', 20]] #sorted的用法 L = ['cat', 'binary', 'big', 'dog'] print sorted(L, key=lambda x: (x[0], x[1], x[2])) #['big', 'binary', 'cat', 'dog']
  1. 正则re.complie作用
    1. re.compile是将正则表达式编译成一个对象,加快速度,并重复使用
  2. a=(1,)b=(1),c=("1") 分别是什么类型的数据?
a=(1,)#tuple b=(1)#int c=("1") #str
  1. 用python删除文件和用linux命令删除文件方法
    1. python:os.remove(文件名)
    2. linux: rm 文件名
  2. 数据库优化查询方法
    1. 外键、索引、联合查询、选择特定字段等等
  3. 简述Django的orm
    1. ORM,全拼Object-Relation Mapping,意为对象-关系映射
    2. 实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要修改代码只需要面向对象编程,orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句,所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite....,如果数据库迁移,只需要更换Django的数据库引擎即可
  1. 什么是迭代器
    1. 迭代是Python最强大的功能之一,是访问集合元素的一种方式。
    2. 迭代器是一个可以记住遍历的位置的对象。
    3. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
    4. 迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
  1. 栈的操作
    1. Stack() 创建一个新的空栈
    2. push(item) 添加一个新的元素item到栈顶
    3. pop() 弹出栈顶元素
    4. peek() 返回栈顶元素
    5. is_empty() 判断栈是否为空
    6. size() 返回栈的元素个数
 
  1. Python 三引号的用法
    1. Python 中三引号可以将复杂的字符串进行赋值。
    2. Python 三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。
    3. 三引号的语法是一对连续的单引号或者双引号(通常都是成对的用)。
  2. 关系型运算符优先级高到低为:not and or
  3. 字符串前缀
    1. 前面加f,相当于format(),后面的字符串可以带变量
    2. 前面加r,去除转义字符,后面的文件夹不转义
    3. 前面加b,后面字符串是bytes类型
    4. 前面加u,后面字符串用Unicode格式进行编码。建议所有编码都用utf8
  4. pytest的5种运行模式
    1. 运行后生成测试报告(htmlreport)
      1. 安装:pip install -U pytest-html
      2. 运行:pytest --html=report.html
    2. 运行指定case
      1. 模式1:直接运行test_se.py文件中的所有cases
        1. pytest test_se.py
      2. 模式3:运行test_se.py文件中的TestClassTwo这个class下的test_one:
        1. pytest test_se.py::TestClassTwo::test_one
    3. 多进程运行cases
      1. 安装:pip install -U pytest-xdist
      2. 运行:pytest test_se.py -n NUM
    4. 重试运行cases:
      1. 安装:pip install -U pytest-rerunfailures
      2. 运行:pytest test_se.py --reruns NUM
    5. 显示print内容
      1. 运行:pytest test_se.py -s
      2. pytest的多种运行模式是可以叠加执行的,比如说,你想同时运行4个进程,又想打印出print的内容。可以用:
        1. pytest test_se.py -s -n 4

声明 欢迎转载,但请保留文章原始出处:) 博客园:https://www.cnblogs.com/chenxiaomeng/ 如出现转载未声明 将追究法律责任~谢谢合作
原文地址:https://www.cnblogs.com/chenxiaomeng/p/14728507.html