先了解一下python的知识结构图(转)
一、Python基础
1 代码中要修改不可变数据会出现什么问题?抛出什么异常?
代码不会正常运行,抛出TypeError异常。
2 print调用Python中底层的什么方法?
print方法默认调用sys.stdout.write方法,即往控制台打印字符串。
3 python怎么定义类?
class 类名(继承类):
pass
class Child1(Parent):
pass
4 、input()和raw_input()有什么区别?
Python3:
input():不管输入什么,获取的都是字符串类型的;
Python2:
raw_input():raw_input()和Python3中的input()作用是一样的,不管输入什么,都是获取字符串。
input():输入的是什么数据类型的,获取到的就是什么数据类型的。
5 、
zip() 函数的用法?
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
(python3中返回的是zip对象)
什么是‘可迭代的对象’?
迭代:python中可以用for循环使用取值操作过程.
可迭代对象:可以使用for循环遍历的对象,我们称之为可迭代对象
迭代器:提供数据和记录位置。
生成器:如果函数中有yield我们称之为生成器。
python三大器?(这里是补充,后面还会继续讲)
- 迭代器: 有__iter__()和__next__()方法
- 生成器:函数中将return换成yield
- 装饰器:闭包的本质。
6、 Python2 中,range和xrange的区别?
两者用法相同,不同的是:
①range返回的结果是一个列表,而xrange的结果是一个生成器。
②前者是直接开辟一块内存空间来保存列表,后者是边循环边使用,只有使用时才会开辟内存空间。
所以当列表很长时,使用xrange性能要比range好。
7、 4G内存怎么读取一个5G的数据?
方法一: 可以通过生成器,分多次读取,每次读取数量相对少的数据(比如500MB)进行处理,处理结束后在读取后面的 500MB的数据。
方法二: 可以通过linux命令split将数据切割成小文件,然后再对数据进行处理,此方法效率比较高。可以按照行数切割,可以按照文件大小切割。
8、 read、readline和readlines的区别? read:读取整个文件。 readline:读取下一行,使用生成器方法。 readlines:读取整个文件到一个迭代器以供我们遍历。
8、python怎么写路径?
(1)复制粘贴前面加个r:比如 r'C:\360Downloads\Software’。反斜杠(enter上边的),转义符,需要加r。
(2)不加r的是'C:/360Downloads/Software’ 斜杠是数字键旁边的,除号。
9、 介绍一下except的作用和用法?
except: #捕获所有异常
except: <异常名> #捕获指定异常
except:<异常名1, 异常名2> #捕获异常1 或者异常2
except:<异常名>,<数据>#捕获指定异常及其附加的数据
except:<异常名 1,异常名 2><数据>:#捕获异常名 1 或者异常名 2,及附加的数据
10、 Python的各种库:
标准库:os操作系统,time时间,random随机,pymysql连接数据库,threading线程,multiprocessing进程,queue队列。
第三方库: django和flask也是第三方库,requests,virtualenv,selenium,scrapy,xadmin,celery,re,hashlib,md5。
科学计算库:如Numpy,Scipy,Pandas。
11、 unittest是什么?
在Python中,unittest是Python中的单元测试框架。
它拥有支持共享搭建、自动测试、在测试中暂停代码、将不同测试迭代成一组等功能。
12、 模块和包是什么?
模块:
是搭建程序的一种方式。每一个Python代码文件都是一个模块,并可以引用其他的模块,比如对象和属性。
包(包>=模块):
包含许多Python代码的文件夹是一个包。一个包可以包含模块和子文件夹。
13、 Python 是强类型的,动态的,脚本语言。
强类型语言:不允许不同类型相加。
动态语言:不需要先数据类型声明,且确定一个变量的类型是在第一次给它赋值的时候。
脚本语言:一般也是解释型语言,运行代码只需要一个解释器,不需要编译。
14、 什么是解释性语言,什么是编译性语言?
计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
解释性语言在运行程序的时候才会进行翻译。
编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成机器语言(可执行文件)
15、 第三方工具包说明:
16、 工具安装问题:
windows环境:
Python2:
无法安装mysqlclient。
Python3 :
无法安装MySQL-python、 flup、functools32、Gooey、Pywin32、 webencodings。
matplotlib在python3环境中安装报错:The following required packages can not be built:freetype, png。需要手动下载安装源码包安装解决。 scipy在Python3环境中安装报错,numpy.distutils.system_info.NotFoundError,需要自己手工下载对应的安装包,依赖numpy,pandas必须严格根据python版本、操作系统、64位与否。运行matplotlib后发现基础包 numpy+mkl安装失败,需要自己下载,国内暂无下载源
centos环境下
Python2无法安装mysql-python和mysqlclient包,报错:EnvironmentError: mysql_config not found,解决方案是安装mysql-devel包解决。使用matplotlib报错:no module named _tkinter,安装Tkinter、tk-devel、tc-devel解决。 pywin32也无法在centos环境下安装。
17、 关于Python程序的运行方面,有什么手段能提升性能?
1、使用多进程,充分利用机器的多核性能 2、对于性能影响较大的部分代码,可以使用C或C++编写 3、对于IO阻塞造成的性能影响,可以使用IO多路复用来解决 4、尽量使用Python的内建函数 5、尽量使用局部变量(少用全局变量)
18、 你所遵循的代码规范是什么?请举例说明其要求?
PEP8规范:
1. 变量
常量:大写加下划线 USER_CONSTANT。
私有变量 : 小写和一个前导下划线 _private_value。 Python中不存在私有变量一说,若是遇到需要保护的变量,使用小写和一个前导下划线。但这只是程序员之间的一个约定,用于警告说明这是一个私有变量,外部类不要去访问它。但实际上,外部类还是可以访问到这个变量。
内置变量 : 小写,两个前导下划线和两个后置下划线: __class__ 两个前导下划线会导致变量在解释期间被更名。这是为了避免内置变量和其他变量产生冲突。用户定义的变量要严格避免这种风格。以免导致混乱。
2. 函数和方法
总体而言应该使用,小写和下划线。但有些比较老的库使用的是混合大小写,即首单词小写,之后每个单词第一个字母大写,其余小写。但现在,小写和下划线已成为规范。
私有方法 :小写和一个前导下划线 这里和私有变量一样,并不是真正的私有访问权限。同时也应该注意一般函数不要使用两个前导下划线(当遇到两个前导下划线时,Python 的名称改编特性将发挥作用)。
特殊方法 :小写和两个前导下划线,两个后置下划线 这种风格只应用于特殊函数,比如操作符重载等。
函数参数 : 小写和下划线,缺省值等号两边无空格
3. 类
类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。类名应该简明,精确,并足以从中理解类所完成的工作。常见的一个方法是使用表示其类型或者特性的后缀,例如: SQLEngine,MimeTypes对于基类而言,可以使用一个 Base 或者 Abstract 前缀BaseCookie,AbstractGroup
4. 模块和包
除特殊模块 __init__ 之外,模块名称都使用不带下划线的小写字母。 若是它们实现一个协议,那么通常使用lib为后缀,例如: import smtplib import os import sys
5. 关于参数
5.1 不要用断言来实现静态类型检测。
断言可以用于检查参数,但不应仅仅是进行静态类型检测。 Python 是动态类型语言,静态类型检测违背了其设计思想。断言应该用于避免函数不被毫无意义的调用。
5.2 不要滥用 *args 和 **kwargs。
*args 和 **kwargs 参数可能会破坏函数的健壮性。它们使签名变得模糊,而且代码常常开始在不应该的地方构建小的参数解析器。
6. 其他
6.1 使用 has 或 is 前缀命名布尔元素 is_connect = True has_member = False
6.2 用复数形式命名序列 members = ['user_1', 'user_2']
6.3 用显式名称命名字典 person_address = {'user_1':'10 road WD', 'user_2' : '20 street huafu'}
6.4 避免通用名称 诸如 list, dict, sequence 或者 element 这样的名称应该避免。
6.5 避免现有名称 诸如 os, sys 这种系统已经存在的名称应该避免。
7. 一些数字
一行列数 : PEP 8 规定为 79 列。根据自己的情况,比如不要超过满屏时编辑器的显示列数。 一个函数 : 不要超过 30 行代码, 即可显示在一个屏幕类,可以不使用垂直游标即可看到整个函数。 一个类 : 不要超过 200 行代码,不要有超过 10 个方法。一个模块 不要超过 500 行。
8. 验证脚本
可以安装一个pep8脚本用于验证你的代码风格是否符合PEP8。
19、 Linux查看某个服务的端口?
netstat -anp | grep service_name
20、 10个常用的Linux命令?
pwd 显示工作路径
ls 查看目录中的文件
cd /home 进入 '/ home' 目录'
cd .. 返回上一级目录
cd ../.. 返回上两级目录
mkdir dir1 创建一个叫做 'dir1' 的目录'
rm -f file1 删除一个叫做 'file1' 的文件',-f参数,忽略不存在的文件,从不给出提示。
rmdir dir1 删除一个叫做 'dir1' 的目录' groupadd group_name 创建一个新用户组
groupdel group_name 删除一个用户组
tar -cvf archive.tar file1 创建一个非压缩的
tarball tar -cvf archive.tar file1 file2 dir1 创建一个包含了 'file1', 'file2' 以及 'dir1'的档案文件
tar -tf archive.tar 显示一个包中的内容
tar -xvf archive.tar 释放一个包
tar -xvf archive.tar -C /tmp 将压缩包释放到 /tmp目录下
tar -cvfj archive.tar.bz2 dir1 创建一个bzip2格式的压缩包
tar -xvfj archive.tar.bz2 解压一个bzip2格式的压缩包
tar -cvfz archive.tar.gz dir1 创建一个gzip格式的压缩包
tar -xvfz archive.tar.gz 解压一个gzip格式的压缩包
21、 切片操作
变量.split(‘切片符号’)
22、 程序分析包,比较代码执行效率:
import random
import cProfile
lIn = [random.random() for i in range(100000)]
cProfile.run('f1(lIn)')
cProfile.run('f2(lIn)')
cProfile.run('f3(lIn)’)
二、Python进阶
1 map函数和reduce函数?
①从参数方面来讲:
map()包含两个参数,第一个参数是一个函数,第二个是序列(列表 或元组)。其中,函数(即 map 的第一个参数位置的函数)可以接收一个或多个参数。
reduce()第一个参数是函数,第二个是序列(列表或元组)。但是,其函数必须接收两个参数。
②从对传进去的数值作用来讲:
map()是将传入的函数依次作用到序列的每个元素,每个元素都是独自被函数“作用”一次 。
reduce()是将传入的函数作用在序列的第一个元素得到结果后,把这个结果继续与下一个元素作用(累积计算)。
2 递归函数停止的条件?
def A(n):
if n :
return #退出条件
else:
return #递归条件
4 Python中is和==的区别?
is判断的是a对象是否就是b对象,是通过id来判断的。
==判断的是a对象的值是否和b对象的值相等,是通过value来判断的。
5 Python的魔法方法:
魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现 (重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。 它们经常是两个下划线包围来命名的(比如 __init__,__lt__),Python 的魔法方法是非常强大的,所以了解其使用方法也变得尤为重要!
__init__ :构造器,当一个实例被创建的时候初始化的方法。但是它并不是实例化调用的第一个方法。
__new__:才是实例化对象调用的第一个方法,它只取下 cls 参数,并把其他参数传给 __init__。 __new__很少使用,但是也有它适合的场景,尤其 是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。
__call__: 允许一个类的实例像函数一样被调用 。
__getitem__: 定义获取容器中指定元素的行为,相当于 self[key] 。
__getattr__ :定义当用户试图访问一个不存在属性的时候的行为 。
__setattr__ :定义当一个属性被设置的时候的行为 。
__getattribute__: 定义当一个属性被访问的时候的行为 。
6 谈谈你对面向对象的理解?
面向对象是相对于面向过程而言的。面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;而面向对象是一种基于结构分析的、以数据为中心的程序设计思想。在面向对象语言中有一个有很重要东西,叫做类。
面向对象有三大特性:封装、继承、多态。
7.python面向对象技术:
(1)封装:类的实现就是封装技术。
属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限;
(2)继承:子类、父类。
子类需要复用父类里面的属性或者方法,当然子类还可以提供自己的属性和方法;
(3)多态:以封装和继承为前提,不同的子类对象调用相同的方法,产生不同的执行结果。
(多态是python设计的核心,也叫鸭子类型)
#以下例子,两个子类修改了各自的talk()方法,这也是能形成多态的原因。
#这里的call_talk()可以放很多类似于talk()的方法,以实现多个函数的多态,这就是call_talk()的意义。
class Human(object): #父类
def __init__(self, name):
self.name = name
def talk(self): # 自己定义talk方法
print('这是人')
def call_talk(self): #多态
self.talk()
class Woman(Human): #子类Woman
def talk(self): #重写talk
print('%s很美丽' % self.name)
class Man(Human): #子类Man
def talk(self): #重写talk
print('%s很帅气' % self.name)
class People(Human): # 继承
pass
human = Human('')
human.call_talk()
man = Man('女人')
man.call_talk()
woman = Woman('男人')
woman.call_talk()
people = People('')
people.call_talk()
输出:
8.python三大器详解:
(1)迭代器:
就是定义一个类,在类里面实现iter和next这两个方法;则这个类就是 迭代器。
可迭代,可以用for循环遍历。
意义:
节省内存,可迭代,可以用for循环遍历。
示例:
class Fibonacci(object):
def __init__(self, num):
# num:表示生成多少fibonacci数字
self.num = num
# 记录(斐波拉契数列)fibonacci前两个值,
self.a = 0
self.b = 1
# 记录当前生成数字的索引
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index < self.num:
result = self.a
self.a, self.b = self.b, self.a + self.b
self.current_index += 1
return result
else:
raise StopIteration
fib = Fibonacci(5)
print(next(fib))
print(next(fib))
print('迭代')
for value in fib:
print(value)
结果:
(2)生成器:(函数,return换为yeild)
函数中将return换成yield,就是生成器函数。generator 生成器,是一个函数。
意义:
本质就是迭代器,只不过yeild里封装了,不用写__iter__()和__next__()。也是为了节省内存。
可迭代,可以用for循环遍历。
示例:
def fibonacci(n):
a,b,count=0,1,0
while True:
if count>n:
break
yield a
count+=a
a,b=b,a+b
fib=fibonacci(5)
print(next(fib))
print(next(fib))
print('迭代')
for i in fib:
print(i)
结果:
(3)装饰器:
在不改变一个函数代码和调用方式的情况下给函数添加新的功能。闭包的本质。
在B函数前@一下A函数,就可以把B函数作为参数加入A函数中执行。
示例:
在原先的函数func()的基础上,添加计算运行时间的功能。
一个@time_it的装饰器(代码如下所示)。如果你想打印出某个函数或程序运行时间,只需在函数前面@一下
import time
def time_it(func):
def inner():
start = time.time()
func()
end = time.time()
print('用时{}秒'.format(end-start))
return inner
#这个是原先的函数,加了个@time_it,就作为参数传入time_it,执行time_it函数内的inner()函数。
@time_it
def func1():
time.sleep(0.5)
print("Func1 is running.")
if __name__ == '__main__':
func1()