- 为什么学习Python?
python的优势
Python是开源、免费、跨平台(Windows、Linux、macOS等等)的编程语言,这三个特性使得它有非常广泛的应用
在计算机领域,它是一种被广泛使用的高级编程语言,具有现在高级编程语言的特性,完全面向对象,其中的函数、模块、数字、字符串都是对象。
Python通常被称作“脚本语言”。这是因为它同Perl、Ruby等语言一样是动态类型编程语言,动态型语言的特性使它具有动态类型系统和垃圾回收机制,能够自动管理内存,那么编程者就可以专注在程序的思想和逻辑上,可以更快速的实现程序功能。
动态语言的运行需要一个叫做“解释器”(interpreter)的“中间人”程序,它能够把高级编程语言一行一行地解释运行。每次运行动态语言编写的程序时,都要先通过解释器这个“中间人”解释转换成字节码(Bytecode)并运行这些字节码,因此运行速度比较慢。但是,
请不要纠结Python运行速度慢,要充分利用Python的方便快捷
合适的工具可以达到事半功倍的效果
Python的设计哲学就是“优雅”、“明确”、“简单”,让开发者“用一种方法,最好是只有一种方法来做一件事”。Python 这种崇尚简洁的哲学,再加上多年积攒下来的库(模块),让开发者如虎添翼快捷的完成很多工作。
Python的运行速度慢是经常被人诟病的,但是它很好的支持用C、C++进行扩展,把计算耗时的算法用C、C++实现并编译成Python模块供其调用,可以大大提高运行速度。这种支持其它语言扩展的特性就像胶水一样,把不同的语言仅仅连接在一起,因此,Python也被成为“胶水语言”。
Life is short ,You need python!
人生苦短,我用python
- 通过什么途径学习的Python?
自学 (买书,视频,搜索。。。)
- Python和Java、PHP、C、C#、C++等其他语言的对比?
1 python代码 优雅,简单易懂
Python的设计哲学就是“优雅”、“明确”、“简单”,让开发者“用一种方法,最好是只有一种方法来做一件事”。Python 这种崇尚简洁的哲学,再加上多年积攒下来的库(模块),让开发者如虎添翼快捷的完成很多工作。
2 Python的运行速度慢是经常被人诟病的,但是它很好的支持用C、C++进行扩展,把计算耗时的算法用C、C++实现并编译成Python模块供其调用,可以大大提高运行速度。这种支持其它语言扩展的特性就像胶水一样,把不同的语言仅仅连接在一起,因此,Python也被成为“胶水语言”。
没有一种语言是银弹,只有最适合。
- 简述解释型和编译型编程语言?
其实Python和Java/C#一样,也是一门基于虚拟机的语言
属于编译型语言的是: C
属于解释型语言的是: php asp jsp
java具有编译与解释两种特性:既可以将其源代码当作脚本执行,也可以进行编译成.class代码(字节码)载入运行。
区别在于:
编译型语言,通常都会对源代码进行编译,生成可以执行的二进制代码,执行的是编译后的结果。
解释型语言,通常不用对源代码进行编译,一般是通过解释器载入脚本后运行。由于每个语句都是执行的时候才进行解释翻译,这样解释性语言每次执行就要翻译一次,效率相对要低
- Python解释器种类以及特点?
Cpython,IPython,Jpython,pypy,Ironpython
Python是一门解释器语言,代码想运行,必须通过解释器执行,Python存在多种解释器,分别基于不同语言开发,每个解释器有不同的特点,但都能正常运行Python代码,以下是常用的五种Python解释器:
CPython:当 从Python官方网站下载并安装好Python2.7后,就直接获得了一个官方版本的解
释器:Cpython,这个解释器是用C语言开发的,所以叫 CPython,在命名行下运行python,
就是启动CPython解释器,CPython是使用最广的Python解释器。
IPython:IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方
式上有所增强,但是执行Python代码的功能和CPython是完全一样的,好比很多国产浏览器
虽然外观不同,但内核其实是调用了IE。
PyPy:PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,
对Python代进行动态编译,所以可以显著提高
Python代码的执行速度。
Jython:Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
IronPython:IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,
可以直接把Python代码编译成.Net的字节码。
在Python的解释器中,使用广泛的是CPython,对于Python的编译,除了可以采用以上解释器
进行编译外,技术高超的开发者还可以按照自己的需求自行编写Python解释器来执行Python代码,十分的方便!
- 位和字节的关系?
位 bit
字节 byte
1byte = 8bit
- b、B、KB、MB、GB 的关系?
1B = 8b
B KB MB GB 都是1024进位
1GB=1024MB
1MB=1024KB
1KB=1024B
- 请至少列举5个 PEP8 规范(越多越好)。
1、缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
2、每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
3、不要在一句import中多个库,比如import os, sys不推荐
4、逗号、冒号、分号前不要加空格。
5、总体原则,避免不必要的空格
6、类的方法第一个参数必须是self,而静态方法第一个参数必须是cls
- 通过代码实现如下转换:
二进制转换成十进制:v = “0b1111011”
十进制转换成二进制:v = 18
八进制转换成十进制:v = “011”
十进制转换成八进制:v = 30
十六进制转换成十进制:v = “0x12”
十进制转换成十六进制:v = 87
二进制转换成十进制:v = "0b1111011"
int(v,2)
十进制转换成二进制:v = 18
bin(v)
八进制转换成十进制:v = "011"
int(v,8)
十进制转换成八进制:v = 30
oct(30)
十六进制转换成十进制:v = "0x12"
int(v,16)
十进制转换成十六进制:v = 87
hex(v)
-
请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:10 00001010 3 00000011 9 00001001 12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
int(reduce(lambda x,y:x+y,[f"{int(x):08b}" for x in "10.3.9.12".split(".")]),2)
python递归的最大层数?
windows下是998次
linux 是996次
可以调整
import sys
sys.setrecursionlimit(100000)
我们已经将数字调到足够大了,已经大于系统堆栈,python已经无法支撑到太大的递归了。
对于没有尾递归的编程语言来说,程序运行起来的时候计算机会给当前进程分配栈,每递归一次,计算机就会给当前程序调度一部分来使用,当使用过多了,那么不好意思,我就这么点了。然后,就没有然后了,崩了。python不是尾递归优化的语言,我们不应该使用递归来替代掉循环,循环存在必然有它巨大的意义。递归用于复杂度为O(log(n))的计算是很有意义的,用于O(n)就不怎么好了。
那么有什么好的解决办法呢?当然是有的,比如python的generator,这个是python的一大神器,请参看:http://www.jianshu.com/p/d36746ad845d
- 求结果:
v1 = 1 or 3
v2 = 1 and 3
v3 = 0 and 2 and 1
v4 = 0 and 2 or 1
v5 = 0 and 2 or 1 or 4
v6 = 0 or False and 1
此题中变量是数字 # 判断变量是否为0, 是0则为False,非0判断为True,
# and中含0,返回0; 均为非0时,返回后一个值, # or中, 至少有一个非0时,返回第一个非0,
v1 1
v2 3
v3 0
v4 1
v5 1
v6 False
- ascii、unicode、utf-8、gbk 区别?
都是字符集编码
ascii:
A:00000010 8位 一个字节
unicode:
A:00000000 00000001 00000010 00000100 32位 四个字节
中:00000000 00000001 00000010 00000100 32位 四个字节
utf-8:
A:00000110 8位 一个字节
中:00000010 00000110 16位 两个字节
gbk:
A:00000110 8位 一个字节
中:00000010 00000110 16位 两个字节
1,各个编码之间的二进制,是不能互相识别的,会产生乱码。
2,文件的存储,传输,不能是unicode (只能是utf-8 utf-16 gbk gbk2312 ascii等)
- 字节码和机器码的区别?
字节码:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
机器码:机器码就是计算机可以直接执行,并且执行速度最快的代码。
- 三元运算规则以及应用场景?
三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值
三元运算符的功能与'if....else'流程语句一致,它在一行中书写,代码非常精炼,执行效率更高
格式:[on_true] if [expression] else [on_false]
res = 值1 if 条件 else 值2
- 列举 Python2和Python3的区别?
1、print
在python2中,print被视为一个语句而不是一个函数,python3中,print()被视为一个函数
2、整数的除法
在python2中,键入的任何不带小数的数字,将被视为整数的编程类型。比如5/2=2,解决方法:5.0/2.0=2.5
在python3中,整数除法变得更直观 5/2=2.5
3、Unicode
Python 2 默认使用 ASCII 字母表;Python 3 默认使用 Unicode
4、后续发展
Python 2.7 将在 2020 年失去后续的支持,
Python 3 将继续开发更多的功能和修复更多的错误。
- 用一行代码实现数值交换:
a = 1
b = 2
a = 1
b = 2
a,b = b,a
- Python3和Python2中 int 和 long的区别?
int(符号整数):通常被称为是整数,没有小数点的正或负整数;
long(长整数):无限大小的整数,这样写整数和一个大写或小写的L。
- xrange和range的区别?
range: 函数说明,range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个列表。
xrange:函数说明,xrange 用法与 range 完全相同,所不同的是生成的不是一个list对象,而是一个生成器。
1、range和xrange都是在循环中使用,输出结果一样。
2、range返回的是一个list对象,而xrange返回的是一个生成器对象(xrange object)。
3、xrange则不会直接生成一个list,而是每次调用返回其中的一个值,内存空间使用极少,因而性能非常好。
- 文件操作时:xreadlines和readlines的区别?
二者使用时相同,但返回类型不同,xreadlines返回的是一个生成器,readlines返回的是list
- 列举布尔值为False的常见值?
0 , [ ] , " , ( ) , { }
- 字符串、列表、元组、字典每个常用的5个方法?
字符串常用 split replace startswith endswith count index find center strip
# # 列表
sample_list = ['a', 1, ('a', 'b')] # 创建列表
sample_list = ['a', 'b', 0, 1, 3] # Python列表操作
value_start = sample_list[0] # 得到列表中的某一个值
end_value = sample_list[-1] # 得到列表中的某一个值
del sample_list[0] # 删除列表的第一个值
sample_list[0:0] = ['sample value'] # 在列表中插入一个值
# 元组
#元组也是一个list,他和list的区别是元组的元素无法修改
tuple1 = (2, 3, 4, 5, 6, 4, 7)
print(type(tuple1))
print(tuple1[:7])
print(tuple1[: 5: -1])
for i in range(6):
print(tuple1[i])
for i in tuple1:
print(i)
# 字典
D.get(key, 0) # 同dict[key],多了个没有则返回缺省值,0。[]没有则抛异常
D.has_key(key) # 有该键返回TRUE,否则FALSE
D.keys() # 返回字典键的列表
D.clear() # 清空字典,同del dict
D.copy() # 拷贝字典
D.update() # 更新字典
- lambda表达式格式以及应用场景?
lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
add = lambda x, y : x+y
print(add(1,2)) # 结果为3
应用在函数式编程中 应用在闭包中
- pass的作用?
1、空语句 do nothing
2、保证格式完整,保证语义完整
3、占位语句
- *arg和**kwarg作用
*args:可以理解为只有一列的表格,长度不固定。
**kwargs:可以理解为字典,长度也不固定。
1、函数调用里的*arg和**kwarg:
(1) *arg:元组或列表“出现”
**kwarg:字典“出没”
(2)分割参数
2、函数定义时传的*arg /**kwarg:
(1)接收参数
- is和==的区别
is是对比地址(id),==是对比值
- 简述Python的深浅拷贝以及应用场景?
浅拷贝:copy.copy 深拷贝:copy.deepcopy
浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层
就是浅拷贝的原理,l2拷贝l1的时候只拷贝了他的第一层,也就是在其他内存中重新创建了l1的第一层数据,但是l2无法拷贝l1的第二层数据,也就是列表中的列表,所以他就只能指向l1中的第二层数据
主要应用在字符串,数字的深浅拷贝
- Python垃圾回收机制?
Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通
过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题。通过“分代回收”(generation collection)以空间换取时间来进一步提高垃圾回收的效率。
- Python的可变类型和不可变类型?
Python的每个对象都分为可变和不可变
可变:列表、字典 不可变:数字、字符串、元组
- 求结果:
v = dict.fromkeys(['k1','k2'],[])
v[‘k1’].append(666)
print(v)
v[‘k1’] = 777
print(v)
求结果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}
- 求结果
def num():
return [lambda x:i*x for i in range(4)]
print([ m(2) for m in num()])
[6,6,6,6]
- 列举常见的内置函数?
bin() hex() int() str() dict() range() ord() chr() sum() print() open()
- filter、map、reduce的作用?
通俗的说.这三者都是用在一堆数据(比如一个列表)上.
map是用同样方法把所有数据都改成别的..字面意思是映射..比如把列表的每个数都换成其平方.,返回的是map对象,要用list转换成列表
list(map(lambda x: x*x,[1,2,3,4,]))
reduce是用某种方法依次把所有数据丢进去最后得到一个结果..字面意思是化简..比如计算一个列表所有数的和的过程,就是维持一个部分和然后依次把每个数加进去.
from functools import reduces
reduce(lambda x,y: x+y,[1,2,3,4])
filter是筛选出其中满足某个条件的那些数据..字面意思是过滤..比如挑出列表中所有奇数
list(filter(lambda x: x % 2 ==1,[1,2,3,4,]))
- 一行代码实现9*9乘法表
print('\n'.join([' '.join(['%s*%s=%-2s' % (y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)]))
- 如何安装第三方模块?以及用过哪些第三方模块?
pip install xxx
- 至少列举8个常用模块都有那些?
os sys time datetime math json re random
- re的match和search区别?
match从头匹配
search从内容匹配
- 什么是正则的贪婪匹配?
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配
re.search(r'a.?c','abcabcdef').group()
abcabc
非贪婪匹配:就是匹配到结果就好,就少的匹配字符
默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式
re.search(r'a.*?c','abcabcdef').group()
abc
- 求结果: a. [ i % 2 for i in range(10) ] b. ( i % 2 for i in range(10) )
a [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
b 是一个生成器
- 求结果: a. 1 or 2 b. 1 and 2 c. 1 < (2==2) d. 1 < 2 == 2
print(1 or 2) # 1
print(1 and 2) # 2
print(1<(2==2)) # False 因为2==2为True,而True表示为1,False表示为0,所以1<1,结果为False
print(1<2==2) # True python是允许连续比较1<2==2意思是1<2且2==2
- def func(a,b=[]) 这种写法有什么坑?
def func(a,b=[]):
b.append(a)
print(b)
func(1)
func(1)
func(1)
func(1)
看下结果
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list,第二次执行还是用第一次执行的时候实例化的地址存储,所以三次执行的结果就是 [1, 1, 1] ,想每次执行只输出[1] ,默认参数应该设置为None。
- 如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
"1,2,3".split(",")
- 如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
[int(i) for i in "1,2,3".split(",")]
- 比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 c = [(1,),(2,),(3,) ] 的区别?
a,b都是列表,c是无组
B_list和C_list中元素的区别,虽然都带了小括号,但是中间加一个逗号,和不加逗号是俩种类型。特别注意
- 如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?
[x*x for x in range(1,11)]
- 一行代码实现删除列表中重复的值 ?
l = [1,2,3,4,1,3]
sorted(set(l),key=l.index)
l1 = []
for i in l:
if i not in l1:
l1.append(i)
- 如何在函数中设置一个全局变量 ?
global a
a = 10
- logging模块的作用?以及应用场景?
可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;
- 请用代码简答实现stack 。
class Stack(object):
def __init__(self):
self.stack = []
def push(self, value): # 进栈
self.stack.append(value)
def pop(self): #出栈
if self.stack:
self.stack.pop()
else:
raise LookupError('stack is empty!')
def is_empty(self): # 如果栈为空
return bool(self.stack)
def top(self):
#取出目前stack中最新的元素
return self.stack[-1]
- 常用字符串格式化哪几种?
第一种:最方便的
缺点:需一个个的格式化
print('hello %s and %s'%('df','another df'))
第二种:最好用的
优点:不需要一个个的格式化,可以利用字典的方式,缩短时间
print('hello %(first)s and %(second)s'%{'first':'df', 'second':'another df'})
第三种:最先进的
优点:可读性强
print('hello {first} and {second}'.format(first='df',second='another df'))
第四种python3.6以上
print(f'hello {"df"} and {"another df"}'.format(first='df', second='another df'))
- 简述 生成器、迭代器、可迭代对象 以及应用场景?
迭代器:是访问集合元素的一种方式,从集合的第一个元素开始访问,直到所有元素被访问结束。其优点是不需要事先准备好整个迭代过程中的所有元素,仅在迭代到某个元素时才开始计算该元素。适合遍历比较巨大的集合。__iter__():方法返回迭代器本身, __next__():方法用于返回容器中下一个元素或数据。
生成器:带有yield的函数不再是一个普通函数,而是一个生成器。当函数被调用时,返回一个生成器对象。不像一般函数在生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行状态。
'''迭代器'''
print('for x in iter([1, 2, 3, 4, 5]):')
for x in iter([1, 2, 3, 4, 5]):
print(x)
'''生成器'''
def myyield(n):
while n>0:
print("开始生成...:")
yield n
print("完成一次...:")
n -= 1
for i in myyield(4):
print("遍历得到的值:",i)
- 用Python实现一个二分查找的函数。
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
def binary_search(dataset,find_num):
if len(dataset) > 1:
mid = int(len(dataset) / 2)
if dataset[mid] == find_num: # find it
print("找到数字", dataset[mid])
elif dataset[mid] > find_num: # 找的数在mid左面
print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
return binary_search(dataset[0:mid], find_num)
else: # 找的数在mid右面
print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
return binary_search(dataset[mid + 1:], find_num)
else:
if dataset[0] == find_num: # find it
print("找到数字啦", dataset[0])
else:
print("没的分了,要找的数字[%s]不在列表里" % find_num)
binary_search(data,20)
- 谈谈你对闭包的理解?
外函数:函数A的内部定义了函数B,那么函数A就叫做外函数
内函数:函数B就叫做内函数
什么是闭包?
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
def outer(a):
b = 10
def inner():
return a+b
return inner
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
- os和sys模块的作用?
sys模块主要是用于提供对python解释器相关的操作
函数
sys.argv #命令行参数List,第一个元素是程序本身路径
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.modules.keys() #返回所有已经导入的模块列表
sys.modules #返回系统导入的模块字段,key是模块名,value是模块
sys.exc_info() #获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) #退出程序,正常退出时exit(0)
sys.hexversion #获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version #获取Python解释程序的版本信息
sys.platform #返回操作系统平台名称
sys.maxint # 最大的Int值
sys.stdout #标准输出
sys.stdout.write('aaa') #标准输出内容
sys.stdout.writelines() #无换行输出
sys.stdin #标准输入
sys.stdin.read() #输入一行
sys.stderr #错误输出
sys.exc_clear() #用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix #返回平台独立的python文件安装的位置
sys.byteorder #本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
sys.copyright #记录python版权相关的东西
sys.api_version #解释器的C的API版本
sys.version_info #'final'表示最终,也有'candidate'表示候选,表示版本级别,是否有后继的发行
sys.getdefaultencoding() #返回当前你所用的默认的字符编码格式
sys.getfilesystemencoding() #返回将Unicode文件名转换成系统文件名的编码的名字
sys.builtin_module_names #Python解释器导入的内建模块列表
sys.executable #Python解释程序路径
sys.getwindowsversion() #获取Windows的版本
sys.stdin.readline() #从标准输入读一行,sys.stdout.write("a") 屏幕输出a
sys.setdefaultencoding(name) #用来设置当前默认的字符编码(详细使用参考文档)
sys.displayhook(value)#如果value非空,这个函数会把他输出到sys.stdout(详细使用参考文档)
os模块
OS模块是Python标准库中的一个用于访问操作系统功能的模块,使用OS模块中提供的接口,可以实现跨平台访问
用于提供系统级别的操作
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","new") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep 当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 用于分割文件路径的字符串
os.name 字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值.即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.lexists #路径存在则返回True,路径损坏也返回True
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.commonprefix(list) #返回list(多个路径)中,所有path共有的最长的路径。
os.path.expanduser(path) #把path中包含的"~"和"~user"转换成用户目录
os.path.expandvars(path) #根据环境变量的值替换path中包含的”$name”和”${name}”
os.access('pathfile',os.W_OK) 检验文件权限模式,输出True,False
os.chmod('pathfile',os.W_OK) 改变文件权限模式
带进度条的复制文件代码
import sys
import time
import os
import shutil
import math
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=100)
def changeTime(allTime):
day = 24 * 60 * 60
hour = 60 * 60
min = 60
if allTime < 60:
return "%d sec" % math.ceil(allTime)
elif allTime > day:
days = divmod(allTime, day)
return "%d days, %s" % (int(days[0]), changeTime(days[1]))
elif allTime > hour:
hours = divmod(allTime, hour)
return '%d hours, %s' % (int(hours[0]), changeTime(hours[1]))
else:
mins = divmod(allTime, min)
return "%d mins, %d sec" % (int(mins[0]), math.ceil(mins[1]))
def view_bar(num, total):
rate = float('{:.2f}'.format(num / total))
rate_num = int(rate * 100)
# r = ‘\r %d%%‘ %(rate_num)
r = '\r%s>%d%%' % ('=' * rate_num, rate_num,)
sys.stdout.write(r)
sys.stdout.flush
def cpwithprocess(srcfile, dstfile):
try:
st = time.time()
srcsize = os.path.getsize(srcfile)
executor.submit(shutil.copy, srcfile, dstfile)
dstsize = 0
while dstsize < srcsize:
time.sleep(0.3)
view_bar(dstsize, srcsize)
dstsize = os.stat(dstfile)[6]
else:
view_bar(100, 100)
except Exception as e:
print(e)
finally:
et = time.time()
usetime = changeTime(round(et-st))
print("\n用时:"+usetime)
cpwithprocess(r'e:\java_pid5115.zip', r'd:\java_pid5115.zip')
- 如何生成一个随机数?
import random
random.randint(1,10)
- 如何使用python删除一个文件?
import os
os.remove('xxx')
os.unlint('xxx')
- 谈谈你对面向对象的理解?
什么是封装?
所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面,这就是封装。封装是我们所说的面相对象编程的特征之一。除此之外还有继承和多态。
什么是继承?
继承有点类似与我们生物学上的遗传,就是子类的一些特征是来源于父类的,儿子遗传了父亲或母亲的一些性格,或者相貌,又或者是运动天赋。有点种瓜得瓜种豆得豆的意思。面向对象里的继承也就是父类的相关的属性,可以被子类重复使用,子类不必再在自己的类里面重新定义一回,父类里有点我们只要拿过来用就好了。而对于自己类里面需要用到的新的属性和方法,子类就可以自己来扩展了。
什么是多态?
我们在有一些方法在父类已经定义好了,但是子类我们自己再用的时候,发现,其实,我们的虽然都是计算工资的,但是普通员工的工资计算方法跟经理的计算方法是不一样的,所以这个时候,我们就不能直接调用父类的这个计算工资的方法了。这个时候我们就需要用到面向对象的另一个特性,多态。我们要在子类里面把父类里面定义计算工资的方法在子类里面重新实现一遍。多态包含了重载和重写。
什么是重写?
重写很简单就是把子类从父亲类里继承下来的方法重新写一遍,这样,父类里相同的方法就被覆盖了,当然啦,你还是可以通过super.CaculSalary方法来调用父类的工资计算方法。
什么是重载?
重载就是类里面相同方法名,不同形参的情况,可以是形参类型不同或者形参个数不同,或者形参顺序不同,但是不能使返回值类型不同。
- Python面向对象中的继承有什么特点?
继承的优点:
1、建造系统中的类,避免重复操作。
2、新类经常是基于已经存在的类,这样就可以提升代码的复用程度。
继承的特点:
1、在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。有别于C#
2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
3、Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
- 面向对象深度优先和广度优先是什么?
- 面向对象中super的作用?
什么是super?
super() 函数是用于调用父类(超类)的一个方法。
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
语法
以下是 super() 方法的语法:
super(type[, object-or-type])
参数
·type -- 类
·object-or-type -- 类,一般是 self
Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx :
Python3.x 实例:
class A:
pass
class B(A):
def add(self, x):
super().add(x)
Python2.x 实例:
class A(object): # Python2.x 记得继承 object
pass
class B(A):
def add(self, x):
super(B, self).add(x)
具体应用示例:
举个例子
class Foo:
def bar(self, message):
print(message)
>>> Foo().bar("Hello, Python.")
Hello, Python.
当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,例如:
技术分享图片
class FooParent:
def bar(self, message):
print(message)
class FooChild(FooParent):
def bar(self, message):
FooParent.bar(self, message)
>>> FooChild().bar("Hello, Python.")
Hello, Python.
技术分享图片
这样做有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,另外,Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。为了解决这些问题,Python引入了super()机制,例子代码如下:
技术分享图片
class FooParent:
def bar(self, message):
print(message)
class FooChild(FooParent):
def bar(self, message):
super(FooChild, self).bar(message)
>>> FooChild().bar("Hello, Python.")
Hello, Python
技术分享图片
表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的结果是一致的,实际上这两种方法的内部处理机制大大不同,当涉及多继承情况时,就会表现出明显的差异来,直接给例子:
代码一:
技术分享图片
class A:
def __init__(self):
print("Enter A")
print("Leave A")
class B(A):
def __init__(self):
print("Enter B")
A.__init__(self)
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
A.__init__(self)
print("Leave C")
class D(A):
def __init__(self):
print("Enter D")
A.__init__(self)
print("Leave D")
class E(B, C, D):
def __init__(self):
print("Enter E")
B.__init__(self)
C.__init__(self)
D.__init__(self)
print("Leave E")
E()
技术分享图片
结果为:
Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Enter D
Enter A
Leave A
Leave D
Leave E
执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。
代码二:
技术分享图片
class A:
def __init__(self):
print("Enter A")
print("Leave A")
class B(A):
def __init__(self):
print("Enter B")
super(B, self).__init__()
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
super(C, self).__init__()
print("Leave C")
class D(A):
def __init__(self):
print("Enter D")
super(D, self).__init__()
print("Leave D")
class E(B, C, D):
def __init__(self):
print("Enter E")
super(E, self).__init__()
print("Leave E")
E()
技术分享图片
结果:
Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E
在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照MRO(Method Resolution Order):方法解析顺序 进行的。
- 是否使用过functools中的函数?其作用是什么?
functools用于高阶函数:指那些作用于函数或者返回其他函数的函数。通常情况下,只要是可以被当做函数调用的对象就是这个模块的目标。
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2(‘1000000‘)
64
>>> int2(‘1010101‘)
85
- 列举面向对象中带爽下划线的特殊方法,如:new、init
__new__是一个静态方法,而__init__是一个实例方法.
__new__方法会返回一个创建的实例,而__init__什么都不返回.
只有在__new__返回一个cls的实例时后面的__init__才能被调用.
当创建一个新实例时调用__new__,初始化一个实例时用__init__.
- 如何判断是函数还是方法?
函数:
函数是封装了一些独立的功能,可以直接调用,python内置了许多函数,同时可以自建函数来使用。
方法:
方法和函数类似,同样封装了独立的功能,但是方法是需要通过对象来调用的,表示针对这个对象要做的操作,使用时采用点方法。
- 静态方法和类方法区别?
@staticmethod和@classmethod
Python其实有3个方法,
即静态方法(staticmethod),
类方法(classmethod)
和实例方法,如下:
def foo(x):
print "executing foo(%s)"%(x)
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
a=A()
这里先理解下函数参数里面的self和cls.这个self和cls是对类或者实例的绑定,对于一般的函数来说我们可以这么调用foo(x),这个函数就是最常用的,它的工作跟任何东西(类,实例)无关.对于实例方法,我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self, x),为什么要这么做呢?因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的a.foo(x)(其实是foo(a, x)).类方法一样,只不过它传递的是类而不是实例,A.class_foo(x).注意这里的self和cls可以替换别的参数,但是python的约定是这俩,还是不要改的好.
对于静态方法其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.
\ 实例方法 类方法 静态方法
a = A() a.foo(x) a.class_foo(x) a.static_foo(x)
A 不可用 A.class_foo(x) A.static_foo(x)
- 列举面向对象中的特殊成员以及应用场景
1. __doc__ 描述类的信息
2. __dict__ 查看类或对象中的所有成员
- 1、2、3、4、5 能组成多少个互不相同且无重复的三位数
def threeNum(l):
lists = []
for i in l:
for j in l:
for k in l:
if i != j and i != k and j != k:
num = str(i)+str(j)+str(k)
lists.append(num)
return set(lists) # l中有重复元素时候去重
l = [1, 2, 3, 4, 5]
print(len(threeNum(l)))
- 什么是反射?以及应用场景?
这就是python的反射,它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
这段话,不一定准确,但大概就是这么个意思。
class common():
def login():
return 'login'
print(common.__dict__)
inp = input("请输入:").strip()
if hasattr(common,inp):
res = getattr(common, inp)
print(res())
- metaclass作用?以及应用场景?
- 用尽量多的方法实现单例模式。
- 装饰器的写法以及应用场景。
装饰器是一个工厂函数,接受一个函数作为参数,然后返回一个新函数,其闭包中包含被装饰的函数。有了装饰器,可以提取大量函数中与本身功能无关的类似代码 ( 这块在Flask中用于定义路由的@app.route,就是一个很好的例子),达到代码重用的目的。可应用于插入日志、性能测试、事务处理等方面
不修改原函数代码,扩展功能
开发的开放封闭原则,已实现的代码不允许修改,允许扩展
def w1(func):
def inner():
# 验证1
# 验证2
# 验证3
return func()
return inner
@w1
def f1():
print 'f1'
@w1
def f2():
print 'f2'
@w1
def f3():
print 'f3'
@w1
def f4():
print 'f4'
- 异常处理写法以及如何主动抛出异常(应用场景)
def test(a, b):
try:
if b == 3:
raise ValueError("aaaa")
else:
print(a/b)
except ZeroDivisionError as e:
print(e)
else:
print("else")
finally:
print("finally")
test(1,0)
- 什么是面向对象的mro
MRO(Method Resolution Order 方法解析顺序)是面向对象中用于查询类的多继承的继承顺序的方法,
它是基于算法来实现的,不同的算法实现的MRO的顺序不同
- isinstance作用以及应用场景?
isinstance判断一个对象是不是某个类型
a = 1
if isinstance(a,int):
xxxx
- 写代码并实现:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
l = [2, 7, 11, 15]
target = 13
for i, v in enumerate(l):
# print(i, v)
x = target - v
# print(l.index(x))
# xindex = [i for i, v in enumerate(l) if v == x]
if x in l and l.index(x) != i:
print([i, l.index(x)])
break
class Solution(object):
@staticmethod
def twoSum(nums, target):
""" :type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums) <= 1:
return False
buff_dict = {}
for i in range(len(nums)):
if nums[i] in buff_dict:
print([buff_dict[nums[i]], i])
return [buff_dict[nums[i]], i]
else:
buff_dict[target - nums[i]] = i
Solution.twoSum(nums=l, target=target)
- json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
基本数据类型 int str dict list tuple
import json
from json import JSONEncoder
from datetime import datetime
class ComplexEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
else:
return super(ComplexEncoder, self).default(obj)
d = {'name': 'alex', 'data': datetime.now()}
print(json.dumps(d, cls=ComplexEncoder))
- json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
import json
s = "中文"
dd =json.dumps(s,ensure_ascii=False)
- 什么是断言?应用场景?
assert()方法,断言成功,则程序继续执行,断言失败,则程序报错
In [71]: a = 3
In [72]: assert(a>1)
In [73]: print("断言成功,程序继续向下执行")
断言成功,程序继续向下执行
In [74]: b = 5
In [75]: assert(b>9)
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-75-e543486a620d> in <module>
----> 1 assert(b>9)
AssertionError:
- 有用过with statement吗?它的好处是什么?
with 语句实质是上下文管理。
1、上下文管理协议。包含方法__enter__() 和 __exit__(),支持该协议对象要实现这两个方法。
2、上下文管理器,定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。
3、进入上下文的时候执行__enter__方法,如果设置as var语句,var变量接受__enter__()方法返回值。
4、如果运行时发生了异常,就退出上下文管理器。调用管理器__exit__方法。
- 使用代码实现查看列举目录下的所有文件。
import os
def main():
'''
读取制定路径下的所有文件
'''
dir_aim = raw_input("请输入所要查看的文件目录:")
for root, dirs, files in os.walk(dir_aim):
print 'root:', root
if files:
print 'File:'
for file in files:
print file,
print ''
if dirs:
for dir in dirs:
print dir
if __name__=='__main__':
main()
- 简述 yield和yield from关键字。
当函数中有yield关键字的时候,这个函数就是生成器,可以用for循环或者next()来迭代
yield from iterable是for item in iterable: yield item的语法糖。
yield from range(5) == for i in range(5): yield i