1、什么是Python?使用Python有什么好处?#Python知识分享#重在理解
Python是一种动态解释型编程语言,包含对象,模块,线程,异常和自动内存管理。Python可用于Web应用程序开发,自动化,数学建模,大数据应用程序等领域。也经常被用作“胶水”代码。
Python的好处在于它简单易用,可移植,可扩展,内置数据结构,并且它是一个开源的。
动态语言:在运行时确定数据类型的语言变量类型在运行期是可变的;当声明变量或类似变量时,不需要声明变量的类型。
解释型:与C语言等语言不同,Python不需要在运行之前进行编译。
2、什么是PEP 8
PEP 8是一个编码风格约定,关于如何编写Python代码更具可读性。
3、Python是如何解释语言的?
Python 代码在运行前,会先将.py 文件编译生成.pyc字节码文件(中间代码,与平台无关,不管放在 Windows 还是 Linux 平台都可以执行),运行时将由虚拟机逐行把字节码翻译成机器语言给CPU执行。
介绍Cython、Pypy、Cpython、Numba各有什么缺点
Cython是让Python脚本支持C语言扩展的编译器,Cython能够将Python+C混合编码的.pyx脚本转换为C代码,主要用于优化Python脚本性能或Python调用C函数库。
Pypy最重要的一点就是Pypy集成了JIT(一种混合了解释器和编译器好处的技术,将源代码编译成了本地机器码),通过编译技术提升脚本解释器系统的速度。同时针对CPython的缺点进行了各方面的改良,性能得到很大的提升。Pypy的优点是对纯Python项目兼容性极好,几乎可以直接运行并直接获得性能提升;缺点是对很多C语言库支持性不好,Pypy社区有相关讨论。
Numba是一个库,使用LLVM编译技术来解释字节码,可以在运行时将Python代码编译为本地机器码,而不会强制大幅度的改变普通的Python代码。
通用性:Cython和Numba的兼容性都非常好,而Pypy对于部分库的支持较差(如Numpy,Scipy)。
速度:这三种方案的速度相差不大,通常来说Cython要快于Pypy,尤其是对于部分C扩展。Pypy要快于Numba,但针对于纯数值计算的工作,Numba甚至还要快于Cython。
易用性:易用性最好的无疑是Pypy,Pypy是Python的解释器,我们针对纯Python使用Pypy,除了Pypy不支持的部分库外,不需要进行任何改动。然后是Numba,Numba的基本使用方法就是给函数加一个装饰器,易用性也很高,最后是Cython,因为Cython中需要使用Python+C混合编码,如果需要移植,代价会很大。
CPython是用C语言实现的Python解释器,也是官方的并且是最广泛使用的Python解释器。
4、Python是如何进行内存管理的及调优手段
主要有三个方面
一、对象的引用计数机制
使用引用计数来保持追踪内存中的对象,所有对象都有引用计数。
二、垃圾回收机制
对象的引用计数归零时,它将被垃圾收集机制处理掉
三、内存池机制
Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
垃圾回收机制:
通过引用计数进行垃圾回收(对象创建时+1,销毁时-1,计数0时解释器适当的时候回收);
通过 “标记-清除” (使用 gc.collect() 立即回收)解决容器对象可能产生的循环引用问题(引用计数0时一直不能回收);
调优手段:
1.手动垃圾回收
2.调高垃圾回收阈值
3.避免循环引用(手动解循环引用和使用弱引用)
5、当Python退出时,为什么不清除所有分配的内存?
1)当Python退出时,没有被解除分配或释放(有些对其他对象具有循环引用的Python模块或从全局名称空间引用的对象)
2)无法解除分配C库保留的那些内存部分。
3)退出时,由于拥有自己的高效清理机制,Python会尝试取消分配/销毁其他所有对象。
内存泄露是什么?如何避免?
内存泄露指应该被清理却没有被清理的内存一直占据着系统资源造成浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
避免:1.手动垃圾回收 2.调高垃圾回收阈值 3.避免循环引用(手动解循环引用和使用弱引用)
哪些操作会导致Python内存溢出,怎么处理?
内存溢出:内存不够。
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;处理:采用多次查询,边查询边处理边清除
存在死循环或递归调用; 处理:清除或优化
存在因循环而重复产生的新对象实体; 处理:优化
存在使用定义对象后未清空的现象; 处理:手动清除
6、什么是Python decorators?
Python decorators(装饰器),作用是改变其他函数的运作方式(嵌入或修改代码),这可以使得代码更加简洁和强大。
python新式类和经典类的区别?
在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性;反之,即不由任意内置类型派生出的类,则称之为“经典类”。
“新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”。
7、list和tuple有什么区别?
列表是可变的而元组不是。元组可以被散列,例如作为词典的关键。元组比列表快。
8、Python中的字典是什么?
一种可变容器模型,且可存储任意类型对象。字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {}
d = {key1 : value1, key2 : value2 }
9、Dict和List理解是什么?
它们是语法结构,可以根据现有的iterable轻松创建Dictionary或List。
10、Python数组和列表的区别?
Python中的数组和列表具有相同的存储数据方式。但是,数组只能包含单个数据类型元素,而列表可以包含任何数据类型元素。
11、列出python中可变数据类型和不可变数据类型有哪些,并简述原理
可变类型(mutable):改变了变量的值后不会新建一个对象,变量引用的对象的地址也不会变化,有List、Sets、Dictionaries
不可变类型(immutable):改变了变量的值后, 新建一个对象,而对于相同的值的对象,在内存中则只有一个对象(一个地址),有Strings、Tuples、Numbers、bool
12、在Python中切片是什么,以及[:: -1]、[:-1]、[2::-1]表示什么?
从序列类型(如列表,元组,字符串等)中选择一部分的机制称为切片。
[:: -1]用于反转数组或序列的顺序。
[:-1]除了最后一个取全部
[2::-1]取从下标为2的元素翻转读取
13、Python中的反向索引是什么?
Python序列可以是正数和负数的索引。对于正索引,0是第一个索引,1是第二个索引,依此类推。对于负索引,( - 1)是最后一个索引,( - 2)是倒数第二个索引,依此类推。
例子:a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
14、Python中的类型转换?
int() - 将任何数据类型转换为整数类型
float() - 将任何数据类型转换为float类型
ord() - 将字符转换为整数
hex() - 将整数转换为十六进制
oct() - 将整数转换为八进制
tuple() -此函数用于转换为元组
set() -此函数在转换为set后返回类型
list() -此函数用于将任何数据类型转换为列表类型
dict() -此函数用于将顺序元组(键,值)转换为字典
str() -用于将整数转换为字符串
complex(real,imag) - 此函数将实数转换为复数(实数,图像)数
15、什么是序列化和非序列化?
将对象(或变量)转换为可通过网络传输或可以存储到本地磁盘的数据格式(如:XML、JSON或特定格式的字节串)的过程称为序列化(picking);反之,则称为反序列化(unpicking)。
记忆方法:
# 序列化,数据到文件,就dump # 反序列化,文件到数据,就load # 根据字符串转换就加s # 从文件直接转就不加s
16、Python中的命名空间是什么?
命名空间是一个命名系统,用于确保名称是唯一性,以避免命名冲突。
17、什么是PYTHONPATH?
它是导入模块时使用的环境变量。每当导入模块时,也会查找PYTHONPATH以检查各个目录中是否存在导入的模块。解释器使用它来确定要加载的模块。
18、如何在Windows上安装Python并设置路径变量?
控制面板-系统与安全-系统-高级系统设置-环境变量-系统变量path
19、Python中的module和package是什么?
在Python中,模块是构造程序的方式。每个Python程序文件都是一个模块,它导入其他模块,如对象和属性。
Python程序的文件夹是一个模块包。包可以包含模块或子文件夹。
一些常用的内置模块包括:sys、math、random、data time、JSON。
20、如何跨模块共享全局变量?
要在单个程序中跨模块共享全局变量,请创建一个特殊模块。在应用程序的所有模块中导入配置模块。该模块将作为跨模块的全局变量提供。
21、Python中的函数是什么?
函数是一个代码块,只有在被调用时才会执行。要在Python中定义函数,需要使用def关键字。
编写函数的4个原则
1)函数设计要尽量短小,嵌套层次不宜过深。
2)参数个数不宜太多。
3)函数参数设计应该考虑向下兼容。
4)一个函数只做一件事情,尽量保证函数语句粒度的一致性。
python函数重载机制?
函数重载:基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用。
重载主要是为了解决两个问题。 1。可变参数类型。 2。可变参数个数。
对于情况 1 ,函数功能相同,但是参数类型不同,python 如何处理?答案是根本不需要处理,因为 python 可以接受任何类型的参数,如果函数的功能相同,那么不同的参数类型在 python 中很可能是相同的代码,没有必要做成两个不同函数。
对于情况 2 ,函数功能相同,但参数个数不同,python 如何处理?答案就是缺省参数。对那些缺少的参数设定为缺省参数即可解决问题。因为你假设函数功能相同,那么那些缺少的参数终归是需要用的。
所以python 自然就不需要函数重载了。
为什么函数名字可以当做参数用?
根据代码执行顺序由上自下、从左至右来的(心里一点把握也没有)
什么是回调函数,有什么好处?
回调函数就是一个被作为参数传递的函数。
回调允许函数调用者在运行时调整原始函数的行为。因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。回调函数使得程序设计更加灵活。
递归函数停止的条件?
1、判断递归的次数是否达到某一限定值
2、判断运算的结果是否达到某个范围等,根据设计的目的来选择
python常见的列表推导式?
列表推导式语法规范:
out_list =
[out_express_res for out_express in input_list if out_express_condition]
out_express_res : 列表生成元素表达式,可以是有返回值的函数。
for out_express in input_list:迭代input_list将out_express传入out_express_res表达式中。
if out_express_condition:根据条件过滤哪些值可以。
这种语法称为列表推导式
字典推导式、集合推导式把中括号改成大括号即可
解释一下什么是闭包?
在一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行。这样的函数称之为闭包。
对缺省参数的理解 ?
有默认值的参数叫做缺省参数。
22、为什么使用* args,** kwargs?
当不确定将多少个参数传递给函数,或者想要将存储的列表或参数元组传递给函数时,使用* args。当不知道将多少关键字参数传递给函数时使用**kwargs,或者它可以用于将字典的值作为关键字参数传递。标识符* args和* * kwargs是一个约定,你也可以使用* bob和** billy。
23、参数如何通过值或引用传递?
如果传递的参数是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。
如果传递的参数是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值'来传递对象。
24、局部变量和全局变量是如何定义的?
全局变量:在函数外部定义变量,在任何函数动能调用
局部变量:在一个函数内部定义变量只能在这个函数可以用,在其他函数用不了
如何在函数中设置一个全局变量 ?
global
函数内局部变量与全局变量名同名,优先调用局部变量
以下计算题会报错 UnboundLocalError: local variable 'num' referenced before assignment
Python中变量的作用域?(变量查找顺序)
作用域类型
1)函数中的局部作用域:local
2)嵌套函数中父级函数的局部作用域:enclosing
3)全局作用域:global
4)系统内置的变量:如 int、str、list 等关键字
变量的查找顺序为:局部作用域 > 父级函数作用域 > 当前模块全局作用域 > 系统内置作用域 顺序是按代码执行顺序上方就近原则
简单示例说明
25、什么是lambda函数(匿名函数)?
该函数可以包含任意数量的参数,但只能有一个执行操作的语句。它实际上是一个简化版的函数。
26、为什么python中的lambda表单没有语句?
因为它用于创建新的函数对象,然后在运行时返回它们。
27、什么是Python中的迭代器?
迭代器是可以遍历或迭代的对象。
28、Python中的生成器是什么?
实现迭代器的函数称为生成器。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
29、Xrange和range有什么区别?
python3里,range()返回迭代器,xrange()不再存在。
range方法返回的是一个list对象,它需要开辟专门的空间保存序列中所有的元素。
xrange方法返回的是xrange对象,它是一个序列对象,但并不保存序列中的元素。
30、如何区分break,continue和pass?
break:跳出循环,不再执行,用在while和for循环中
continue:跳出本次循环,执行下一次
pass:占位,不做任何事情
31、如何把字符串的第一个字母大写?
capitalize()函数可以将字符串的第一个字母大写
32、如何将字符串转换为全小写?
要将字符串转换为小写,可以使用lower()函数。
33、运算符/、//的区别?
" / "就表示 浮点数除法,返回浮点结果;" // "表示整数除法,只返回小数点前面部分。
34、operators中的is、not和in各有什么功能?
is用于判断两个变量引用对象是否为同一个,即同一个内存地址;反之是is not。引用地址比较
not单独使用一般判断变量是否为空
in判断变量是否在另一个变量中,not in则相反。值比较
is和==有什么区别
is用于判断两个变量引用对象是否为同一个,即同一个内存地址;
==只判断值是否相等
35、如何在python中使用三元运算符?
基本语法为:val = a if a > b else b
36、在Python中split(),sub(),subn()功能。
Python的“re”模块提供的3种方法
split() - 使用正则表达式模式将给定字符串“拆分”到列表中。
sub() - 查找正则表达式模式匹配的所有子字符串,然后用不同的字符串替换它们。
subn() - 它类似于sub(),并且还返回新字符串。
37、如何在Python中删除文件?
要在Python中删除文件,您需要导入OS模块。之后,您需要使用os.remove()函数。
38、NumPy中有哪些操作Python列表的函数?
39、如何删除python数组的值?
可以使用pop()或remove()方法删除数组元素。这两个函数之间的区别在于前者返回已删除的值,而后者则不返回。
40、判断一个列表是否所有元素都相等
构造为集合,判断长度
len(set(list))==1
all(x==list[0] for x in list)
list.count(list[0])==len(list)
set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。元素除了是 0、空、None、False 外都算 True。
list.count(obj) 统计某个元素在列表中出现的次数
41、什么是Python补丁?
Python补丁是指在运行时通过类外部的函数对类或模块进行动态修改。
补丁主要有以下几个用处:
在运行时替换方法、属性等
在不修改第三方代码的情况下增加原来不支持的功能
在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加
gevent协程的时候,用到的monkey.patch_all()补丁
42、说几个常见的魔术方法并介绍作用,如__init__?
__new__在内存空间为对象分配空间,返回对象的引用;
__init__初始化对象,定义实例属性
__del__在对象生命周期调用结束时被调用
__call__ 在那些类的实例经常改变状态的时候会非常有效和优雅。
__enter__ 定义了当使用with语句的时候,会话管理器在块被初始创建时要产生的行为
__exit__ 定义了当一个代码块被执行或者终止后,会话管理器应该做什么。
__copy__ 浅拷贝创建新对象,新旧对象中的数据一样,引用同一个地址
__deepcopy__ 深拷贝拷创建新对象,新旧对象中的数据一样,可变数据引用地址不同
描述器
__get__(self, instance, owner):
定义了当描述器的值被取得的时候的行为。instance是拥有该描述器对象的一个实例。owner是拥有者本身
__set__(self, instance, value):
定义了当描述器的值被改变的时候的行为。instance是拥有该描述器类的一个实例。value是要设置的值。
__delete__(self, instance):
定义了当描述器的值被删除的时候的行为。instance是拥有该描述器对象的一个实例。
43、Python中的self是什么?
self是类的实例或对象。init方法中的self变量引用新创建的对象,而在其他方法中,它引用其方法被调用的对象。
Python中类方法、类实例方法、静态方法有何区别?
类方法:是类对象的方法,在定义时需要在上方使用“@classmethod”进行装饰,形参为 cls,表示类对象,类对象和实例对象都可调用;
类实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为 self,指代对象本身;
静态方法:是一个任意函数,在其上方使用“@staticmethod”进行装饰,可以用对象直接调用,静态方法实际上跟该类没有太大关系。
请描述抽象类和接口类的区别和联系
相同
都有抽象方法
都不可以实例化
区别
抽象类:约束子类中必须包含某些方法(允许有普通方法,不需要实现) // 弱约束
接口类:约束子类中必须包含父类规定的方法(没有普通方法,必须全部实现) // 强约束
面向对象中怎么实现只读属性?
1/用私有属性+@property
2/通过__setattr__方法拦截特定属性写入
44、如何在Python中复制对象?
要在Python中复制对象,可以尝试copy.copy()或copy.deepcopy()来处理一般情况。您无法复制所有对象,但大多数对象都是如此。
45、深拷贝和浅拷贝有什么区别?
在创建新实例类型时使用浅拷贝,并保留在新实例中复制的值。浅拷贝用于复制引用指针,就像复制值一样。这些引用指向原始对象,并且在类的任何成员中所做的更改也将影响它的原始副本。浅拷贝允许更快地执行程序,它取决于所使用的数据的大小。
深拷贝用于存储已复制的值。深拷贝不会将引用指针复制到对象。它引用一个对象,并存储一些其他对象指向的新对象。原始副本中所做的更改不会影响使用该对象的任何其他副本。由于为每个被调用的对象创建了某些副本,因此深拷贝会使程序的执行速度变慢。
46、Python有OOps概念吗?
Oops概念的主要目标是实现真实世界的实体,如类、继承、抽象、多态和对象。python自诞生以来就是一种面向对象的语言。面向对象的范例是使用类和对象来设计程序。该对象与诸如书,房子,铅笔等的实词实体相关。oops概念专注于编写可重复使用的代码。
47、解释Python中的继承。
继承允许一个类获得另一个类的所有元素(比如属性和方法)。继承提供代码可重用性,使创建和维护应用程序更容易。被继承的类称为超类,继承的类称为派生/子类。
单一继承 - 派生类获取单个超类的成员。
多级继承 - 从基类base1继承的派生类d1,d2继承自base2。
分层继承 - 从一个基类可以继承任意数量的子类
多重继承 - 派生类从多个基类继承。
48、什么是Python中的多态性?
多态性表示能够采取多种形式。因此如果父类具有名为ABC的方法,则子类也可以具有具有相同名称ABC的方法,该方法具有其自己的参数和变量。Python允许多态。
49、在Python中定义封装?
它用于限制对方法和变量的访问。在封装中, 代码和数据被包装在一个单元中, 以防意外修改。
50、如何在Python中进行数据抽象?
数据抽象仅提供所需的详细信息并将实现隐藏起来。它可以通过使用接口和抽象类在Python中实现。
51、python是否使用了访问说明符?
Python不会限制对实例变量或函数的访问权限。Python规定了使用单个或双下划线为变量,函数或方法的名称添加前缀的概念【私有属性】,类似于受保护和私有访问说明符。
52、如何在Python中创建一个空类?
k = object() 或
k = type('test', (object,), {})()
"""
type(name, bases, dict)
name -- 类的名称。
bases -- 基类的元组。 (object,)去掉,就不被当做元组报错argument 2 must be tuple
dict -- 字典,类内定义的命名空间变量
"""
53、object()函数有什么作用?
它返回一个无特征的对象,它是所有类的基础。此外,它不包含任何参数。
对设计模式的理解,简述你了解的设计模式?
设计模式:大牛们踩过了无数的坑总结出来的软件设计中的推荐方案
几个常见模式
工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类
单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
mvc模式:模型-视图-控制器模式,这种模式用于应用程序的分层开发
适配器模式:实现不兼容接口间兼容
观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新
状态模式:允许对象在其内部状态改变时改变他的行为。
单例模式的应用场景有那些?
日志应用,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
数据库连接,节省打开或者关闭数据库连接所引起的效率损耗
多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
请手写一个单例
对装饰器的理解,并写出一个计时器记录方法执行性能的装饰器?
Python中yield的用法?
1. 每个生成器只能使用一次。
2. yield一般都在def生成器定义中搭配一些循环语句使用。有时候,为了保证生成器函数永远也不会执行到函数末尾,会用while True: 语句,这样就会保证只要使用next(),这个生成器就会生成一个值,是处理无穷序列的常见方法。
54、什么是Python中的单元测试?
Python中的单元测试框架称为unittest。它支持共享设置,自动化测试,测试关闭代码,将测试聚合到集合等。
55、解释如何从C访问用Python编写的模块?
您可以通过以下方法访问C中用Python编写的模块,
Module = PyImport_ImportModule("modulename");
如果模块尚未被导入(即它还不存在于 sys.modules 中),这会初始化该模块;否则它只是简单地返回 sys.modules["modulename"] 的值。 请注意它并不会将模块加入任何命名空间 —— 它只是确保模块被初始化并存在于 sys.modules 中。
之后你就可以通过如下方式来访问模块的属性(即模块中定义的任何名称):
attr = PyObject_GetAttrString(module, "attrname");
56、如何在Python中实现多线程?
主要是通过thread和threading这两个模块来实现多线程支持。thread模块是比较底层的模块,threading模块是对thread做了一些封装,可以更加方便的被使用。但是python(cpython)由于GIL的存在无法使用threading充分利用CPU资源,如果想充分发挥多核CPU的计算能力需要使用multiprocessing模块(Windows下使用会有诸多问题)。
57、Python中的docstring是什么?
Python文档字符串称为docstring,这些文档字符串在三引号内。它们没有分配给任何变量,因此有时也用于注释。
''' say something here!'''
58、Python中help()和dir()函数的用法是什么?
help()函数用于显示文档字符串,还可以查看与模块,关键字,属性等相关的使用信息。
dir()函数用来查询一个类或者对象所有属性。
print(dir(list))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']