目录
一、什么是MRO
所谓的MRO,就是方法解析顺序。在调用方法时,会对当前类以及所有的基类进行一个搜索,确定要调用的方法具体在哪。不管用哪种方式去确定MRO列表,必须满足本地优先级和单调性。
本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。
单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。
二、 你知道MRO列表遵循那几条原则
一个类的MRO列表就是合并所有弗雷德MRO列表,并遵循以下三条原则:
- 子类永远在父类前面
- 如果有多个父类,会根据它们在列表中的顺序被检查
- 如果对下一类存在两个合法地选择,选择第一个父类
三、什么是面向对象?优缺点有那些?面向的语言有哪些?
面向对象基本思想:从现实世界中客观存在的事物出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式。面向对象更加强调运用人类在日常生活的逻辑思维中经常采用的思想方法与原则,如抽象、分类、继承、聚合、堕胎等。
优点:
易维护、易复用、易扩展,由于面向对象有封装、继承、多态的特性,可以设置出低耦合的系统,使系统更加灵活、更加易于维护
缺点:
性能比面向过程低
面向对象的语言有:Smalltalk、Eiffel、C++、C#、Java、PHP、NET等
四、什么是面向过程?优缺点有那些?面向的语言有哪些?
面向过程是一种以过程为中心的编程思想。面向过程也可称之为“面向记录”编程思想,他们不支持丰富的“面向对象”特征,并且它们不允许混合持久化状态和域逻辑。
优点:
性能比面向对象高。因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发
缺点:
没有面向对象易维护、易复用、易扩展
面向过程的语言有:C、pascal
五、面向对象的三大特征
封装
面向对象的程序设计中,某个类把所有需要的数据和对数据的操作全部都封装到类中,分被称为类的成员变量和方法。这种把成员变量和成员函数封装在一起的编程特性成为封装
继承
继承是指可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
多态
多态指的是一类事物有多种形态。如序列类型有多种形态:字符串,列表,元组。多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特征不同的方式运作
六、python之Hook函数(钩子函数)
钩子函数在python称之为Hook函数,它pytest框架的开发者,为了让用户更好的去扩展开发预留的关于pytest中的预留钩子,可以通过开发插件,和在coftest.py去实现这些狗子
定义:
- 是个函数,在系统消息触发时被系统调用
- 不是用户自己触发的
- 使用是直接拍那些函数体
- 钩子函数的名称是确定,当系统消息触发,自动会调用
pytest中的钩子函数按功能一共分为6类:引导钩子、初始化钩子、用例收集钩子、用例执行钩子、报告钩子、调式钩子
七、 引导钩子setuptools
引导挂载要求足够早注册的插件(内部和setuptools插件),可以使用的钩子
def pytest_load_initial_conftests(early_config, parser, args):
'''
在命令行选项解析之前实现初始conftest文件的加载,(即:当在命令行通过 pytest 执行命令时,会先执行该钩子函数)
:param early_config: pytest 配置对象。
:param args: 命令行上传递的参数。
:param parser: 命令行添加的选项。
:return: 注意:该钩子函数只有定义在插件中才会调用,在 conftest 定义则不会调用
'''
def pytest_cmdline_preparse(config, args):
'''(不建议使用)在选项解析之前修改命令行参数'''
def pytest_cmdline_parse(pluginmanager, args):
'''
返回一个初始化的配置对象,解析指定的args。(即:用来初始化配置对象,解析指定的参数)
:param pluginmanager:插件管理器
:param args: 命令行上传递的参数
:return Tips: 该钩子函数只有定义在插件中才会调用,在 conftest 定义则不会调用
'''
def pytest_cmdline_main(config):
'''
要求执行主命令行动作。默认实现将调用configure hooks和runtest_mainloop。(即:调用命令解析钩子 pytest_cmdline_parse 和执行 runtest_mainloop)
:param config: pytest 配置对象
:return:
'''
八、初始化挂载
初始化钩子需要插件和conftest.py文件
pytest_addoption(parser):
'''注册argparse样式的选项和ini样式的配置值,这些值在测试运行开始时被调用一次。'''
pytest_addhooks(pluginmanager):
'''在插件注册时调用,以允许通过调用来添加新的挂载'''
pytest_configure(config):
'''许插件和conftest文件执行初始配置'''
pytest_unconfigure(config):
'''在退出测试过程之前调用'''
pytest_sessionstart(session):
'''在session创建对象之后,执行收集并进入运行测试循环之前调用'''
pytest_sessionfinish(session, exitstatus):
'''在整个测试运行完成后调用,就在将退出状态返回系统之前'''
pytest_plugin_registered(plugin, manager):
'''一个新的pytest插件已注册'''
九、收集钩子collection
pytest_collection(session):
'''执行给定会话的收集协议'''
pytest_collect_directory(path, parent):
'''在遍历目录以获取集合文件之前调用'''
pytest_collect_file(path, parent):
'''为给定的路径创建一个收集器,如果不相关,则创建"无"'''
pytest_pycollect_makitem(collector: pyCollector, name: str, obj: object):
'''返回模块中python对象的自定义项目/收集器,或者返回None。在第一个非无结果处停止'''
pytest_generate_tests(metafunc: Metafunc):
'''生成(多个)对测试函数的参数化调用'''
pytest_make_parametrize_id(config: Config: val: object, argname: str):
'''返回val 将由@pytest.mark.parametrize调用使用的给定用户友好的字符串表示形式,如果挂载不知道,则返回None val'''
pytest_collection_modifyitems(session: Session,config: Config, items: List[Item]):
'''在执行收集后调用,可能会就地过滤或重新排序项目'''
pytest_collection_finish(session: Session):
'''在执行并修改收集后调用'''
十、测试运行(runtest)钩子
pytest_runtestloop(session: Session):
'''执行主运行测试循环(收集完成后)'''
pytest_runtest_protocol(item: Item, nextitem: Optional[Item]):
'''对单个测试项目执行运行测试协议'''
pytest_runtest_logstart(nodeid: str, location: Tuple[str, Optional[int], str]):
'''在运行单个项目的运行测试协议开始调用'''
pytest_runtest_logfinish(nodeid: str, location: Tuple[str, Optional[int], str]):
'''在为单个项目运行测试协议结束时调用'''
pytest_runtest_setup(item: Item):
'''调用已执行测试项目的设置阶段'''
pytest_runtest_call(item: Item):
'''调用已运行测试项目的测试(调用阶段)'''
pytest_runtest_teardown(item: Item, nexttitem: Optional[Item]):
'''调用已执行测试项目的拆卸阶段'''
pytest_runtest_makereport(item: Item, call: CallInfo[None]):
'''被称之为_pytest.reports.TestReport测试项目的每个设置,调用和拆卸运行测试阶段创建一个'''
pytest_pyfunc_call(pyfuncitem: Function):
'''调用基地测试功能'''
十一、报告钩子reporting
pytest_collectstart(collector: Collector):
'''收集器开始收集'''
pytest_make__collect_report(collector: Collector):
'''执行collector.collect()并返回一个CollectReport'''
pytest_itemcollected(item: Item):
'''我们刚刚收集了一个测试项目'''
pytest_collectreport(report: CollectReport):
'''收集器完成收集'''
pytest_deselected(items: Sequence[Item]):
'''要求取消选择的测试项目,例如按关键字'''
十二、调式/相互作用钩
很少有可以用于特殊报告或与异常交互的挂钩
pytest_iniernalerror(excrepr: ExceptionRepr, excinfo: ExceptionInfo[BaseException]):
'''要求内部错误。返回True已禁止对将INTERNALERROR消息直接打印到sys.stderr的回退处理'''
pytest_keyboard_interrupt(excinfo: ExceptionInfo[Union[KeyboardInterrupt, Exit]]):
'''要求键盘中断'''
pytest_exception_interact(node: Union[Item, Collector], call: CallInfo[Any], report: Union[CollectReport, TestReport]):
'''在引发可能可以交互处理的异常时调用'''
pytest_enter_pdb(config: Config, pdb: pdb.pab):
'''调用了pdb.set_trace()'''
十三、什么十鸭子类型
鸭子类型是动态类型的一种风格,在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由“当前方法和属性的集合”决定
class Duck:
def walk(self):
print("Duck can walk")
def fly(self):
print("Duck can fly")
class Parrot:
def walk(self):
print("Parrot can walk")
def fly(self):
print("Parrot can fly")
def test_bird(bird):
bird.walk()
bird.fly()
test_bird(Duck())
test_bird(Parrot())
十四、你知道什么十猴子补丁吗?
这个叫法起源于Zope框架,这也是个Web框架内。类似Django
大家在修正Zope的Bug的时候经常在程序后面追加更新部分
这些被称为是杂牌军补丁
猴子补丁主要有以下几个用处:
- 在行时替换方法、属性等
- 在不修改第三方代码的情况下增加原来不支持的功能
- 运行时为内存中的对象增加补丁,而不是在磁盘的源代码中增加
猴子补丁的主要功能便是在不去改变源码的情况下而对功能进行追加和变更
对于编程过程中使用一些第三方不满足需求的情况下,使用猴子补丁是非常方便的
十五、什么是深浅拷贝,您知道如何实现吗?
浅拷贝:
只拷贝第一层,并没有拷贝深层次,修改第一层不改变,修改深层次的就互相影响了。切片操作也可以实现浅拷贝
深拷贝:
即递归性质的浅拷贝,它会在内存中生成有一套完成一样的内容
修改其中一个变量,不会影响另一个变量。也就是说,深拷贝就是将所有数据重新创建
十六、您能说说文件缓冲区吗?
缓冲文件系统时系统自动在内存中位程序中每一个正在使用的文件开辟一块文件缓冲区
从内存向磁盘写入、输出的数据会先送到内存的缓冲区,等装满缓冲区后一起送到磁盘上
从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区,然后再从缓冲区中将数据送到程序数据区
十七、文件缓冲区的好处有哪些?文件缓冲区的缺点有哪些
优点:
文件缓冲区是暂时存放读写期间的文件数据而在内存区预留的一定空间
使用文件缓冲区可减少读取硬盘的次数
缺点:
由于缓冲区存在,导致写入文件无法直接在文件中查看得到,所以,需要刷新缓冲区
十八、如何使用刷新缓冲区呢?
fp.flush # 刷新写入缓冲区
fp.close # 刷新写入缓冲区且可以稍待关闭文件
十九、你可知道什么是闭包吗?它有哪些优缺点?如何实现呢?
定义:内外函数嵌套,内部函数引用外部函数作用域下的非全局变量,外函数返回内函数对象
优点:为变量续命
缺点:浪费内存
举例:
def wai():
b = 2
def nei():
print('b')
retun nei
func = wai()
二十、您还知道装饰器吗?
定义:Python装饰器就是用于拓展原来函数功能的一种函数,利用了必报的思路,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
这个函数的特殊之处在于它的返回值也是一个函数,是内部闭函数
将装饰器分为三类:普通装饰器、被装饰函数带参、装饰器函数具有参数
举例:
def wai(flag):
def func(f):
def nei(x, y):
ifflag: return f(x, y)
else: return f(x, y)
return nei
return func
@wai(flag=0) # 装饰器函数带参
def abc(x, y):
return x + y
二十一、您知道正则模块/贪婪非贪婪吗?
贪婪模式:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配,尽可能匹配多的字符
非贪婪模式:匹配到结果就好,尽可能匹配少的字符,一般是通过将?号写到匹配次数之后导致
如果是*?匹配,那么代表通过*号的最少次匹配机制进行匹配,也就是0次
如果是*+匹配,那么就是通过+号的最少次匹配进行匹配,也就是1次
二十二、您知道logging模块及起作用吗?
logging是日志模块,可以用来记录用户的行为或者代码执行的过程
可以了解程序的运行情况是否正常
在程序出现故障快速定位出错地方以及故障分析
二十三、您会用JSON模块吗?
JSON是一种轻量级的数据交换格式
由于较多数语言都支持JSON数据解析和封装
于是乎我们现在几乎都是用JSON来进行序列化返回给前端
可以使用不同语言之间进行友好的数据交互
二十四、你知道面向对象的MRO吗?
MRO也就是继承查找顺序
用来确定在多继承情况下,子类查找父类同名属性的顺序
二十五、您知道super方法吗?
super是一个可以在子类中获取父类的一个方法
super还可以用来解决多继承问题
直接用类名调用父类的方法在单继承中是没问题的,但是如果使用多继承会涉及到查找顺序(MRO)、重复调用等种种问题,使用super就可以解决这个问题
二十六、您知道self指针的意义吗?
self用来指向当前实例,在类中,具有self指针指向的属性为实例属性,只可以被实例访问
当实例调用方法或变量时,实例方法的第一个参数会自动传入当前实例,形参名约定俗成self
二十七、你知道反射及反射的意义吗?
反射指的是运行时获取类型定义信息,也经常叫做自省
一个对象能够在运行时,像照镜子一样,反射出其类型信息
简单来说,在Python中,能够通过一个对象,找出其type、class、attribute或method的能力或者是在运行期间得知一个对象的属性、状态等一系列信息
二十八、你知道断言是什么吗?并怎样使用它吗?
Python的assert是用来检查一个条件,这是一种高级的一场形式
如果它为真,就不做任何事,如果它为假,则会抛出Assert Error并且包含错误信息,断言经常用在测试过程中,通过使用给定条件和程序中的条件进行判断,如果抛出异常则所说明着代码有问题
二十九、什么是二分查找算法?
二分查找算法,也叫折半查找算法。
二分查找针对的是一个有序的数据集合,每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前一半
直到找到要查找的元素,或者区间被缩小为0
三十、进程线程的特点您开说说?
进程的特点:进程是CPU分配资源的最小单位
独立性:进程是独立存在的实体,拥有自己独立的资源,拥有自己的私有地址;在没有经过进程本身允许的情况下,一个用户进程不能访问其他进程地址空间
动态性:程序只有一个静态的指令集合,而进程是一个正在系统中活动的指令集合;进程在程序中加入了时间概念,具有自己的生命周期和各种不同的状态
并发性:多个程序可以在单个处理器上并发执行,不会互相影响
线程的特点:线程是CPU调度的最小单位
线程是进程的组成部分,一个线程必须有一个父进程,一个进程可以拥有多个线程,一个程序运行后至少有一个进程,一个进程至少包含一个线程。