解释型和编译型编程语言
解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译。编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件。C/C++ 等都是编译型语言,而Java,C#等都是解释型语言
Python解释器种类以及特点?
五种Python解释器
CPython,官方版本的解释器,C语言开发,命名行下运行
IPython,基于CPython,交互式解释器
PyPy,采用JIT技术,动态编译,显著提高执行速度。
Jython,运行在Java平台上,可以直接把Python代码编译成Java字节码执行
IronPython,运行在微软.Net平台,可以直接把Python代码编译成.Net的字节码
位和字节的关系?
位:"位(bit)"是电子计算机中最小的数据单位。每一位的状态只能是0或1
字节:8个二进制位构成1个"字节(Byte)",它是存储空间的基本计量单位。1个字节可以储存1个英文字母或者半个汉字,换句话说,1个汉字占据2个字节的存储空间。
字:"字"由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长,字是计算机进行数据处理和运算的单位。
b、B、KB、MB、GB 的关系?
b 比特bit / 位
B——字节
KB——千比特
MB——兆比特
GB——吉比特
1 B = 8b (8个bit/ 位) 一个字节(byte)等于8位(bit)
1 kB = 1024 B ;1 MB = 1024 kB ;1 GB = 1024 MB;1TB=1024GB;1PB=1024TB;1EB=1024PB;1ZB=1024EB;1YB=1024ZB;1NB=1024YB;1DB=1024NB
ascii、unicode、utf-8、gbk 区别
ASCII码(American Standard Code for Information Interchange,美国信息互换标准代码)ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符
Unicode的字符通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。
UTF-8,
8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。
GBK(Chinese Internal Code Specification)GBK(汉字内码扩展规范)是采用单双字节变长编码,英文使用单字节编码,完全兼容ASCII字符编码,中文部分采用双字节编码。
机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。
字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码,为了实现特定软件运行和软件环境、与硬件环境无关
列举布尔值为False的常见值?
NONE;False(布尔类型);所有的值为零的数(
0(整型)
0.0(浮点型)
0L(长整型)
0.0+0.0j(复数)
)
""(空字符串);[](空列表);()(空元组);{}(空字典)。
字符串、列表、元组、字典常用的方法?
字符串
s.startswith(str,beg_index,end_index),检查s是否已str开头,是返回True,后2个参数可选,不包含end_index
s.endswith(str,beg_index,end_index),检查s是否已str结束,是返回True,后2个参数可选,不包含end_index
s.join(seq),以s作为分隔符,将seq中的所有元素(字符串表示)合并为一个新的字符串
s.lower(),转换s中所有大写字符为小写 ;s.upper(),小写转大写 ;s.swapcase(),翻转大小写
s.strip(),s.lstrip(),s.rstrip() ,截掉s【首尾】空格
s.replace(s1,s2,num) ,把s中的s1替换成s2,若num指定,替换不超过num次
s.split(str,num),以str为分隔符切片s,若num指定,仅分隔num个字符串
s.splitlines(num),按行分隔,返回列表,若num指定,仅分隔num行
列表:
list.append(obj) 添加对象
list.count(obj) 返回对象在列表中出现的次数
list.index(obj,beg_index,end_index),返回索引值,后2个参数可选,不包含end_index
list.insert(index,obj) 在索引值为index的位置插入obj
list.pop(index) 删除并返回指定位置index的对象,默认是最后一个对象
list.remove(obj) 删除对象obj
list.reverse() 翻转列表list
list.sort(func=None,key=None,reverse=False) 以指定的方式排序列表中的成员,若func和key参数指定,则按照指定的方式比较各个元素,若reverse标志被置为True,则列表以反序排列
元组:不可变的(除了用连接符+把元祖结合在一起)
字典:
dict = {}
dict['name'] = 'venus' 添加元素
del dict['name'] 删除元素
dict.clear() 删除字典中的所有院所
dict.get(key,default) 返回key对应的value值,若没有key,则返回default值
dict.items() 返回一个包含字典中键、值对元祖的列表 dict.keys() , dict.values()
dict.update(dict2) 讲字典dict2中的键值对添加到dict中
lambda表达式
lambda后面跟一个或多个参数,紧跟一个冒号,以后是一个表达式。冒号前是参数,冒号后是返回值。
Lambda是一种匿名函数,当我们需要重复调用某一函数,又不想写那么多代码时可以使用lambda表达式来代替。lambda存在意义就是对简单函数的简洁表示。
pass语句什么也不做,一般作为占位符或者创建占位程序,pass语句不会执行任何操作。
Python垃圾回收机制
Python中的垃圾回收是以引用计数为主,分代收集为辅。引用计数的缺陷是循环引用的问题,在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存。
一行代码打出九九表
print (" ".join(" ".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(1, 10)))
分析代码
v = dict.fromkeys(['k1','k2'],[]) v['k1'].append(666) print(v) v['k1'] = 777 print(v) 结果: {'k2': [666], 'k1': [666]} {'k2': [666], 'k1': 777}
def num():#使用闭包的陷阱,函数num返回一个list
里面保存了4个函数变量,这4个函数都共同的引用了循环变量i
, 也就是说它们共享着同一个变量i
,i
是会改变的,当函数调用时,循环变量i
已经是等于3了,因此4个函数返回的都是6
return [lambda x:i*x for i in range(4)] print([m(2) for m in num()]) 结果: [6, 6, 6, 6]
logging模块的作用?以及应用场景?
该模块定义了为应用程序和库实现灵活事件记录系统的函数和类。
- 程序调试
- 了解软件程序运行情况,是否正常
- 软件程序运行故障分析与问题定位
def func(a,b=[]) 这种写法有什么坑?
函数的默认参数是一个list 当第一次执行的时候实例化了一个list 第二次执行还是用第一次执行的时候实例化的地址存储。
请用代码简单实现stack
# coding:utf8 class Stack: """模拟栈""" def __init__(self): self.items = [] def isEmpty(self): return len(self.items) == 0 def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def peek(self): if not self.isEmpty(): return self.items[len(self.items) - 1] def size(self): return len(self.items) s = Stack() print(s.isEmpty()) s.push(4) s.push('dog') print(s.peek()) s.push(True) print(s.size()) print(s.isEmpty()) s.push(8.4) print(s.pop()) print(s.pop()) print(s.size()) 结果: True dog 3 False 8.4 True 2
常用字符串格式化哪几种?
1.print ('hello %s and %s' % ('df', 'another df') )
2.print( 'hello %(first)s and %(second)s' % {'first': 'df', 'second': 'another df'} )
3.print ('hello {first} and {second}'.format(first='df', second='another df'))
简述 生成器、迭代器、可迭代对象 以及应用场景?
生成器是构造迭代器的最简单有力的工具,与普通函数不同的只有在返回一个值的时候使用yield
来替代return
,然后yield
会自动构建好next()
和iter()
迭代器是通过next()
来实现的,每调用一次他就会返回下一个元素,当没有下一个元素的时候返回一个StopIteration
异常,所以实际上定义了这个方法的都算是迭代器
Python中经常使用for
来对某个对象进行遍历,此时被遍历的这个对象就是可迭代对象,像常见的list
,tuple
都是。如果给一个准确的定义的话,就是只要它定义了可以返回一个迭代器的__iter__
方法,或者定义了可以支持下标索引的__getitem__
方法(这些双下划线方法会在其他章节中全面解释),那么它就是一个可迭代对象。
对闭包的理解?
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。装饰器就是一种的闭包的应用,只不过其传递的是函数。
os和sys模块的作用?
os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
使用python删除一个文件?
os.remove(path)
删除文件 path. 如果path是一个目录, 抛出 OSError错误。如果要删除目录,请使用rmdir().
面向对象的理解?
将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面,这就是封装。封装是我们所说的面相对象编程的特征之一。除此之外还有继承和多态,面向对象里的继承也就是父类的相关的属性,可以被子类重复使用,多态包含了重载和重写。重写很简单就是把子类从父亲类里继承下来的方法重新写一遍,这样,父类里相同的方法就被覆盖了,而重载就是类里面相同方法名,不同形参的情况,可以是形参类型不同或者形参个数不同,或者形参顺序不同,但是不能使返回值类型不同。
Python面向对象中的继承有什么特点?
继承的概念:子类拥有父类的所有方法和属性。继承的传递性,子类拥有父类以及父类的父类中封装的所有属性和方法,Python支持多重继承,也就是一个子类可以有多个父类,父类间用逗号隔开。
特点:
- 在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数。
- Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
- 子类只继承父类所有公有的属性和方法,并且也可以在子类中通过父类名来调用,而对于私有的属性和方法,子类是不进行继承的,因此在子类中是无法通过父类名来访问的。
Python中经典类和新式类的区别:
Python中分为经典类和新式类:
经典类:
class A():
pass
新式类:
class A(object):
pass
所以经典类和新式类的区别就是,在声明类的时候,新式类需要加上object关键字。
区别主要体现在继承上:
Python的类可以继承多个类,Java和C#中则只能继承一个类
Python的类如果继承了多个类,那么其寻找方法的方式有两种
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
面向对象深度优先和广度优先是什么?
深度优先算法:
(1)访问初始顶点v并标记顶点v已访问。
(2)查找顶点v的第一个邻接顶点w。
(3)若顶点v的邻接顶点w存在,则继续执行;否则回溯到v,再找v的另外一个未访问过的邻接点。
(4)若顶点w尚未被访问,则访问顶点w并标记顶点w为已访问。
(5)继续查找顶点w的下一个邻接顶点wi,如果v取值wi转到步骤(3)。直到连通图中所有顶点全部访问过为止。
广度优先算法:
(1)顶点v入队列。
(2)当队列非空时则继续执行,否则算法结束。
(3)出队列取得队头顶点v;访问顶点v并标记顶点v已被访问。
(4)查找顶点v的第一个邻接顶点col。
(5)若v的邻接顶点col未被访问过的,则col入队列。
(6)继续查找顶点v的另一个新的邻接顶点col,转到步骤(5)。直到顶点v的所有未被访问过的邻接点处理完。转到步骤(2)
面向对象中super的作用?
在类的继承里面super()非常常用, 它解决了子类调用父类方法的一些问题, 父类多次被调用时只执行一次, 优化了执行逻辑。
是否使用过functools中的函数?其作用是什么?
functools 模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数。换言之,就是能使用该模块对可调用对象进行处理。
列举面向对象中带双下划线的特殊方法,如:__new__、__init__
在调用对象的构造方法时,Python 会调用 __new__ 创建对象,单后调用__init__ 初始化属性。
特殊方法,两边带双下划线的方法。比如__init__(self,...) 、__del__(self) 、__call__(self, *args) 、__str__(self方法)、__add__、__dic__、__getitem__、__setitem__、__delitem__、__iter__
__init__(self,...) 构造方法,这个方法在创建对象时就会访问
__call__(self, *args) 对象后面+()直接调用call方法,此方法python独有,注意:类后面加()调用执行init方法,对象后面()直接调用call方法
__str__(self方法):str方法中含有什么,则return什么东西,print(对象)就返回什么东西
__add__(self, other)对象相加直接执行
__dic__获取对象中封装的所有字段,用__dic__可以取到,并存放在字段中
__getitem__对象+[],执行getitem方法,并把传入的参数赋值给item。是一个语法对应关系,对应字典中的dict[key]
__setitem__类似于字典中的重新赋值。取对应部位的key和value
__delitem__执行del方法,可以伪造方法以作他用
__iter__生成器作用,返回值可以被迭代,需要使用for执行iter方法
关于python中函数与方法?
- 一个可调用对象是方法和函数,和这个对象无关,仅和这个对象是否与类或实例绑定有关(bound method)。
- 实例方法,在类中未和类绑定,是函数;在实例中,此实例方法与实例绑定,即变成方法。
- 静态方法没有和任何类或实例绑定,所以静态方法是个函数。
- 装饰器不会改变被装饰函数或方法的类型。
- 类实现__call__方法,其实例也不会变成方法或函数,依旧是类的实例。
- 使用callalble() 只能判断对象是否可调用,不能判断是不是函数或方法。
- 判断对象是函数或方法应该使用type(obj)。
静态方法和类方法区别?
class Foo(object): def test(self)://定义了实例方法 print("object") @classmethod def test2(clss)://定义了类方法 print("class") @staticmethod def test3()://定义了静态方法 print("static")
#实例方法只能被实例对象调用,静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。
#实例方法,第一个参数必须要默认传实例对象,一般习惯用self。
#静态方法,参数没有要求。
#类方法,第一个参数必须要默认传类,一般习惯用cls。
子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。
列举面向对象中的特殊成员以及应用场景
__doc__ 表示类的描述信息
__module__ 和 __class__ __module__ 表示当前操作的对象在那个模块 __class__ 表示当前操作的对象的类是什么
__init__ 构造方法,通过类创建对象时,自动触发执行
__del__ 析构方法,当对象在内存中被释放时,自动触发执行
__call__ 对象后面加括号,触发执行
__dict__ 类或对象中的所有成员
__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值
__getitem__、__setitem__、__delitem__用于索引操作,如字典。以上分别表示获取、设置、删除数据;也可以用于列表操作,分别表示获取,切片,删除
__iter__ 用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
什么是反射?以及应用场景?
反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射
metaclass作用?
元类的主要目的就是为了当创建类时能够自动地改变类,元类的主要用途是创建API。一个典型的例子是Django ORM
实现单例模式。
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。
在 Python 中,我们可以用多种方法来实现单例模式:
- 使用模块 (Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成
.pyc
文件,当第二次导入时,就会直接加载.pyc
文件,而不会再次执行模块代码) - 使用
__new__(为了使类只能出现一个实例,我们可以使用
__new__
来控制实例的创建过程)class Singleton(object): _instance = None def __new__(cls, *args, **kw): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1 one = MyClass() two = MyClass()
print(one == two,one is two,id(one), id(two))
结果:
True True 1971097776368 1971097776368 - 使用装饰器(decorator)
- 使用元类(metaclass) (元类(metaclass)可以控制类的创建过程,它主要做三件事:拦截类的创建,修改类的定义,返回修改后的类。)
异常处理写法以及如何主动抛出异常
简单的try….except…else的语法
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
try-finally 语句无论是否发生异常都将执行最后的代码
try:
<语句>
finally:
<语句> #退出try时总会执行
raise
注意:可以使用except语句或者finally语句,但是两者不能同时使用。else语句也不能与finally语句同时使用
我们可以使用raise语句自己触发异常,raise [Exception [, args [, traceback]]],一旦执行了raise 语句,raise后面的语句将不能执行
什么是面向对象的mro
mro即method resolution order,主要用于在多继承时判断调的属性的路径(来自于哪个类)
isinstance作用以及应用场景?
语法:isinstance(object,type)
作用:来判断一个对象是否是一个已知的类型。
其第一个参数(object)为对象,第二个参数(type)为类型名(int...)或类型名的一个列表((int,list,float)是一个列表)。其返回值为布尔型(True or flase)。
若对象的类型与参数二的类型相同则返回True。若参数二为一个元组,则若对象类型与元组中类型名之一相同即返回True。
例如:遍历一个对象,要先判断该实例是否为元组、列表或字典等可迭代类型之一
json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
Python的数据类型有(dict、list、string、int、float、long、bool、None)
import json import datetime class DateEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime.date): return obj.strftime('%Y-%m-%d %H:%M:%S') else: return json.JSONEncoder.default(self, obj) a = datetime.datetime.now() b = json.dumps(a,cls=DateEncoder) print(b) 结果: "2018-06-04 19:23:53"
json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
解决方法
要输出中文需要指定ensure_ascii
参数为False
什么是断言?应用场景?
Python的assert是用来检查一个条件,如果它为真,就不做任何事。如果它为假,则会抛出AssertError并且包含错误信息。
断言用于:
- 防御型的编程
- 运行时检查程序逻辑
- 检查约定
- 程序常量
- 检查文档
有用过with statement吗?它的好处是什么?
with语句的作用是通过某种方式简化异常处理,它是所谓的上下文管理器的一种。
with语句会在嵌套的代码执行之后,自动关闭文件。这种做法的还有另一个优势就是,无论嵌套的代码是以何种方式结束的,它都关闭文件。
列举目录下的所有文件
import
os
os.listdir(
'./'
)
简述 yield和yield from关键字。
yield
是一个类似return
的关键字,只是这个函数返回的是个生成器- 当你调用这个函数的时候,函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象
- 当你使用for进行迭代的时候,函数中的代码才会执行
yield from 表达式允许一个生成器代理另一个生成器, 这样就允许生成器被替换为另一个生成器, 子生成器允许返回值
def g1(x): yield range(x) def g2(x): yield from range(x) it1 = g1(5) it2 = g2(5) print([x for x in it1]) print([x for x in it2]) 结果: [range(0, 5)] [0, 1, 2, 3, 4]