这段代码两个类并没有继承关系为什么可以使用super()?

第一部分 Python基础篇(80题)

平台上的解释器,把python编译成. NET 的字节码

6. 位和字节的关系?

来自英文bit,音译为“比特”,表示二进制位,位是计算机内部数据储存的最小单位。

字节来自英文Byte,音译为“拜特”,习惯上用大写的“B”表示。

字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)。

每级缩进使用 4 个空格。

如果不想搞乱以前的古老的代码的话,可以使用8个空格长的制表符。

续行应该与其包裹元素对齐,要么使用圆括号、方括号和花括号内的隐式行连接来垂直对齐;要么使用悬挂式缩进对齐。使用悬挂式缩进时,应该考虑下面的意见。第一行不应该有参数;使用缩进以便与其他代码区分清楚。

# 与开始的分隔符对齐

# 更多的缩进,更加的清晰

# 没有使用垂直对齐时,禁止把参数放在第一行

# 缩进不够,代码不清晰

绝不要混用制表符和空格。

最流行的 Python 缩进方式是仅使用空格,其次是仅使用制表符。混合着制表符和空格缩进的代码将被转换成仅使用空格。使用带-t选项来调用Python命令行解释器时,代码中非法混用制表符和空格会给出警告。当使用-tt选项时这些警告就会变成错误。高度建议使用这些选项。

对新的项目,强烈建议只使用空格而不是制表符。大多数的编辑器都能轻松做到这一点。

限制所有行的最大长度为 79 个字符。

周围还有很多设备限制每行 80个字符。而且,限制窗口显示 80 个字符可以并排显示多个窗口。有些设备上,默认折行会打乱代码结构,不易理解。因此,请限制所有行的最大长度为 79 个字符。对一大段长文本(文档字符串或注释),推荐限制每行最多72个字符。

较长代码行折行的首选方法是在圆括号、方括号和花括号内使用Python的隐式续行方式。通过圆括号内的表达式的折行来把较长的代码行折成多行。这种方式要优先使用,优先于反斜杠。同时确保适当的续行缩进。二元运算符的首选的折行处是在运算符之后,而不是之前。

顶层函数和类之间使用两个空行。

类的方法之间使用一个空行。

(谨慎地)使用额外的空白行来分隔一组相关的函数。一堆相关的单行代码之间的空白行可以省略(例如,一组dummy implementations)。

在函数中使用空行来(谨慎地)表示不同的逻辑段落。

导入通常应当使用单独的行,例如:

导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前。

导入应该按照以下的顺序分组:

每组导入之间使用空行隔开。

在导入之后放置任何相关的 __all__ 说明书。

非常不推荐在包内导入中使用相对路径导入。对所有导入来说,总是使用绝对包路径导入。尽管PEP 328 在Python 2.5中已经完全实现,但是相对路径导入一直以来都是不推荐的,绝对路径导入更容易移植,而且常常更容易阅读。

不好理解的注释不如没有注释。注释要和代码保持与时俱进!

注释应该是一条完整的句子。如果注释是一个短语或句子,它的第一个字应该大写,除非它是一个小写字母开头的标识符(绝对不要改变标识符的大小写)。

如果注释很短,那么结尾的句号可以省略。块注释通常由一个或多个段落组成, 这些段落由完整的句子构成,每个句子都应该使用句号结尾。

句号结尾的句子后面应该有2个空格。

来自非英语国家的Python程序员:请使用英语写注释,除非你120%肯定你的代码将永远不会被不说你的语言的人阅读。

9. 通过代码实现如下转换:

十进制转换成二进制:v = 18

八进制转换成十进制:v = '011'

十进制转换成八进制:v = 30

十六进制转换成十进制:v = '0x12'

十进制转换成十六进制:v = 87

# 十进制转换成二进制:v = 18

# 十进制转换成八进制:v = 30

# 十进制转换成十六进制:v = 87

10. 请编写一个函数实现将IP地址转换成一个整数。

再将以上二进制拼接起来计算十进制结果:01 = ?

默认的在window上的最大递归层数是998,Python的最大递归层数是可以通过sys.setrecursionlimit()设置的,但是一般默认不会超过这个范围。

在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。

ASCII码一共规定了128个字符的编码,这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。

Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字“严”。具体的符号对应表,可以查询,或者专门的汉字对应表。

需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字“严”的unicode是十六进制数4E25,转换成二进制数足足有15位(101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题,第一个问题是,如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:1)出现了unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。2)unicode在很长一段时间内无法推广,直到互联网的出现。

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

由于ASCII编码不支持中文,因此,当中国人用到计算机时,就需要寻求一种编码方式来支持中文。

于是,国人就定义了一套编码规则:当字符小于127位时,与ASCII的字符相同,但当两个大于127的字符连接在一起时,就代表一个汉字,第一个字节称为高字节(从0xA1-0xF7),第二个字节为低字节(从0xA1-0xFE),这样大约可以组合7000多个简体汉字。这个规则叫做GB2312。

但是由于中国汉字很多,有些字无法表示,于是重新定义了规则:不在要求低字节一定是127之后的编码,只要第一个字节是大于127,就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。这种扩展之后的编码方案称之为GBK标,包括了GB2312的所有内容,同时新增了近20000个新的汉字(包括繁体字)和符号。

但是,中国有56个民族,所以,我们再次对编码规则进行了扩展,又加了近几千个少数民族的字符,于是再次扩展后得编码叫做GB18030。中国的程序员觉得这一系列编码的标准是非常的好,于是统统称他们叫做"DBCS"(Double Byte Charecter Set 双字节字符集)。

14. 字节码和机器码的区别?

机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。

通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。

用机器语言编写程序,编程人员要首先熟记所用计算机的全部指令代码和代码的涵义。

手编程序时,程序员得自己处理每条指令和每一数据的存储分配和输入输出,还得记住编程过程中每步所使用的工作单元处在何种状态。这是一件十分繁琐的工作,编写程序花费的时间往往是实际运行时间的几十倍或几百倍。

而且,编出的程序全是些0和1的指令代码,直观性差,还容易出错。现在,除了计算机生产厂家的专业人员外,绝大多数的程序员已经不再去学习机器语言了。

总结:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难编写,一般从业人员接触不到。

字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。

通常情况下它是已经经过编译,但与特定机器码无关。字节码通常不像源码一样可以让人阅读,而是编码后的数值常量、引用、指令等构成的序列。

字节码主要为了实现特定软件运行和软件环境、与硬件环境无关。字节码的实现方式是通过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为可以直接执行的指令。字节码的典型应用为Java bytecode。

字节码在运行时通过JVM(JAVA虚拟机)做一次转换生成机器指令,因此能够更好的跨平台运行。

总结:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。

15. 三元运算规则以及应用场景?

三元运算符就是在赋值变量的时候,可以加判断,然后根据条件赋值。

去除print语句,加入print()函数实现相同的功能,同样的还有 exec语句,已经改为exec()函数。

1)Python 3.x 去除了long类型,现在只有一种整型——int,但它的行为就像2.x 版本的long

2)新增了bytes类型,对应于2.x版本的八位串

17. 用一行代码实现数值交换:

Python 2 有非浮点数准备的 int 和 long 类型。int类型最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。

在Python 3里,只有一种整数类型int,大多数情况下,和Python 2中的长整型类似。

在py2中,range得到的是一个列表,即

xrange得到的是一个生成器对象, 即

它们的使用都是一样的,比如都可以用for循环遍历所有的值

那么,python3中为什么只有range了呢,这个range其实就是py2中的xrange,而不是range,因为使用生成器可以节约内存。

比如现在有个代码是for i in range(0, 10000),如果还是使用py2中的range的话,那你就会得到一个0到9999的一个列表,这个将会占用你很大的空间,但是使用生成器的话,就会节省很大的资源。

21. 列举布尔值为False的常见值?

22. 字符串、列表、元组、字典每个常用的5个方法?

# 指定位置的前面插入一个元素

# 终极删除,可以删除列表或指定元素或者列表切片,list删除后无法访问

#元组也是一个list,他和list的区别是元组的元素无法修改

23. lambda表达式格式以及应用场景?

lambda表达式,又叫匿名函数,代替一些简单的函数,使得代码看上去更简洁并且可读性高。

expression只能是表达式,不能是语句或者代码块,可以接受多个参数,但是只返回一个值。

pass语句在函数中的作用

编写一个程序时,执行语句部分思路还没有完成,可以用pass语句来占位,也可以当做是一个标记,是要过后来完成的代码。

pass语句在循环中的作用

pass也常用于为复合语句编写一个空的主体,比如说你想一个while语句的无限循环,每次迭代时不需要任何操作。

*arg会把多出来的位置参数转化为tuple

Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。

is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。

==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等。

is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。

27. 简述Python的深浅拷贝以及应用场景?

深浅拷贝用法来自copy模块。

对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。

浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层。所以对于只有一层的数据集合来说深浅拷贝的意义是一样的,比如字符串,数字,还有仅仅一层的字典、列表、元祖等。

深拷贝的时候python将所有数据在内存中新建了一份,所以如果你修改新的模版的时候老模版不会变。

引用计数(python默认):记录该对象当前被引用的次数,每当新的引用指向该对象时,它的引用计数ob_ref加1,每当该对象的引用失效时计数ob_ref减1,一旦对象的引用计数为0,该对象立即被回收。

标记清除:基于追踪回收(tracing GC)技术实现的垃圾回收算法,首先会给所有的活动对象打上标记,然后会把那些没有标记的对象进行回收。

分代回收:python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,比如有年轻代、中年代、老年代,年轻代最先被回收。

29. Python的可变类型和不可变类型?

可变类型:类型的数据经过初始化创建成功后,对应内存地址上的数据可以发生多次局部变化,例如:List,Dict,Set。

不可变类型:类型的数据一旦经过初始化创建成功,对应内存地址上的数据本身便不能发生任何变化,例如:Number,String,Tuple。

32. 列举常见的内置函数?

Python内置函数就是python标准库里(语言自身携带的)函数(公共函数)。

1、abs() 此函数返回数字的绝对值。

2、bin() 返回一个整数 int 的二进制表示。

3、chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。(只能输入数字)

4、dict() 函数用于创建一个字典。

5、enumerate() 将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

6、eval() 函数用来执行一个字符串表达式,并返回表达式的值。

7、float() 函数用于将整数和字符串转换成浮点数。

8、frozenset() 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。

9、getattr() 函数用于返回一个对象属性值。

10、hash() 用于获取取一个对象(字符串或者数值等)的哈希值。

11、hex() 函数用于将10进制整数转换成16进制整数。

12、id() 函数用于获取对象的内存地址。

14、int() 函数用于将一个字符串会数字转换为整型。

15、isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

type() 不会认为子类是一种父类类型,不考虑继承关系。

isinstance() 会认为子类是一种父类类型,考虑继承关系。

如果要判断两个类型是否相同推荐使用 isinstance()。

16、len() 方法返回对象(字符、列表、元组等)长度或项目个数。

17、list() 方法用于将元组转换为列表。

18、locals() 函数会以字典类型返回当前位置的全部局部变量。

19、max() 方法返回给定参数的最大值,参数可以为序列。

20、min() 方法返回给定参数的最小值,参数可以为序列。

21、oct() 函数将一个整数转换成8进制字符串。

22、open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。

23、ord() 函数与chr()函数相反,输入字符返回数字

24、pow() 方法返回 xy(x的y次方) 的值。函数是计算x的y次方,如果z在存在,则再对结果进行取模,其结果等效于pow(x,y) %z

26、range() 函数可创建一个整数列表,一般用在 for 循环中。

27、everse() 函数用于反向列表中元素。

28、round() 方法返回浮点数x的四舍五入值。

29、set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。

30、str() 函数将对象转化字符串

31、sum() 方法对系列进行求和计算。

Map:将一个函数映射到一个输入序列的所有元素上。Map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

Reduce:对参数序列中元素进行累积。

用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果,逐步迭代。

Filter:用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

34. 一行代码实现9*9乘法表

35. 如何安装第三方模块?以及用过哪些第三方模块?

通过pip命令安装第三方模块,如果因为网络问题超时的话,可以通过国内镜像源安装。

如果使用的是Anaconda或者MiniConda的话,通过conda命令安装,同业也可以通过国内镜像源解决网络问题。

36. 至少列举8个常用模块都有那些?

sys模块,标准输入输出

math模块,数学公式

json模块,字符串与其他数据类型转换

random模块,生成随机数

time模块,时间模块

也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none。

38. 什么是正则的贪婪匹配?

总是尝试匹配尽可能多的字符

是尝试匹配尽可能少的字符

函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list,第二次执行还是用第一次执行的时候实例化的地址存储。

通过程序看看这个函数有什么坑吧

三次执行的结果就是 [1, 1, 1] ,想每次执行只输出[1] ,默认参数应该设置为None。

46. 一行代码实现删除列表中重复的值 ?

47. 如何在函数中设置一个全局变量 ?

在函数的内部,通过global声明,使在函数内部中设置一个全局变量,这个全局变量可以在任意的函数中进行调用!

48. logging模块的作用?以及应用场景?

logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。

logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python模块都可以使用这个日志记录功能。所以,你的应用日志可以将你自己的日志信息与来自第三方模块的信息整合起来。

logging模块默认定义了以下几个日志等级:

日志等级(level)

最详细的日志信息,典型应用场景是 问题诊断

信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作

当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的

由于一个更严重的问题导致某些功能不能正常运行时记录的信息

当发生严重错误,导致应用程序不能继续运行时记录的信息

50. 常用字符串格式化哪几种?

f ,{}里只能是变量名;一一对应; python3.6版本以上才能使用

51. 简述 生成器、迭代器、可迭代对象 以及应用场景?

生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用 yield 语句。

在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。

生成器对延迟操作提供了支持.所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。

可以直接作用于for循环的叫可迭代对象,可迭代对象包括以下2种:

52. 用Python实现一个二分查找的函数。

53. 谈谈你对闭包的理解?

关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。

而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。

当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

也就是说,内部函数会在外部函数返回后被执行。

而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其它内部函数。

这些局部变量、参数和函数声明(最初时)的值时外部函数返回时的值,但也会受到内部函数的影响。

闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外包裹了一层作用域,这使得该函数无论在何处调用,优先使用自己外层包裹的作用域。

os:这个模块提供了一种方便的使用操作系统函数的方法。

sys:这个模块可供访问由解释器使用或维护的变量和与解释器进行交互的函数。

总结:os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。

55. 如何生成一个随机数?

random.choice(sequence):从特定序列中随机取一个元素,这里的序列可以是字符串,列表,元组等。

56. 如何使用python删除一个文件?

若想利用python删除windows里的文件,这里需要使用os模块!

os.removedirs(path):递归地删除目录。类似于rmdir(), 如果子目录被成功删除, removedirs() 将会删除父目录;但子目录没有成功删除,将抛出错误。

57. 谈谈你对面向对象的理解?

面向对象是向现实世界模型的自然延伸,这是一种“万物皆对象”的编程思想。在现实生活中的任何物体都可以归为一类事物,而每一个个体都是一类事物的实例。面向对象的编程是以对象为中心,以消息为驱动,所以程序=对象+消息。

面向对象有三大特性,封装、继承和多态。

封装就是将一类事物的属性和行为抽象成一个类,使其属性私有化,行为公开化,提高了数据的隐秘性的同时,使代码模块化。这样做使得代码的复用性更高。

继承则是进一步将一类事物共有的属性和行为抽象成一个父类,而每一个子类是一个特殊的父类–有父类的行为和属性,也有自己特有的行为和属性。这样做扩展了已存在的代码块,进一步提高了代码的复用性。

如果说封装和继承是为了使代码重用,那么多态则是为了实现接口重用。多态的一大作用就是为了解耦–为了解除父子类继承的耦合度。如果说继承中父子类的关系式IS-A的关系,那么接口和实现类之之间的关系式HAS-A。简单来说,多态就是允许父类引用(或接口)指向子类(或实现类)对象。很多的设计模式都是基于面向对象的多态性设计的。

总结一下,如果说封装和继承是面向对象的基础,那么多态则是面向对象最精髓的理论。掌握多态必先了解接口,只有充分理解接口才能更好的应用多态。

58. Python面向对象中的继承有什么特点?

减少代码和灵活制定新类

子类具有父类的属性和方法

子类不能继承父类的私有属性/方法

子类可以修改父类的方法

1、在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。

2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数。

3、Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。

59. 面向对象深度优先和广度优先是什么?

当类是经典类时,多继承情况下,在要查找属性不存在时,会按照深度优先的方式查找下去。

在python2中,没有继承object的类,以及它的子类都称之为经典类

当类是新式类时,多继承情况下,在要查找属性不存在时,会按照广度优先的方式查找下去。

在python3中,统一都是新式类。

在python2中,继承object的类,以及它的子类都称之为新式类。

super() 函数是用于调用父类(超类)的一个方法。

super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

61. 是否使用过functools中的函数?其作用是什么?

functools用于高阶函数:指那些作用于函数或者返回其他函数的函数。通常情况下,只要是可以被当做函数调用的对象就是这个模块的目标。

functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

62. 列举面向对象中带双下划线的特殊方法,如:__new__、__init__

__new__:创建对象时调用,会返回当前对象的一个实例

__init__:创建完对象后调用,对当前对象的一些实例初始化,无返回值

__del__:析构方法,当对象在内存中被释放时,自动触发执行。

__str__:改变对象的字符串显示

__doc__:类的描述信息,该描述信息无法被继承

63. 如何判断是函数还是方法?

通过类方法调用为函数,通过实例化对象调用为方法。

64. 静态方法和类方法区别?

类方法是这个类可以调用的方法,那么参数需要把这个类本身传进去,不需要实例化就可以使用。

静态方法是类中的一个普通函数或者说方法,参数和普通的传参一样,类或者实例化的对象都可以直接使用它,也就是说这个静态方法也不需要实例化就可以调用。

65. 列举面向对象中的特殊成员以及应用场景

__call__对象后面加括号,触发执行

__dict__ 查看类或对象中的所有成员

__str__ 如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值

66. 1、2、3、4、5 能组成多少个互不相同且无重复的三位数

67. 什么是反射?以及应用场景?

python面向对象中的反射:通过字符串的形式操作对象相关的属性。

有的时候,程序不一定要按照预置好顺序执行,而是要按照用户输入的指令选择执行相应的函数,但是用户输入的都是字符串,就需要一种通过字符串来操作对象的方法。

metaclass用来指定类是由谁创建的。

69. 用尽量多的方法实现单例模式。

Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

先执行了类的__new__方法(我们没写时,默认调用object.__new__),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式。

此方法是在__new__方法的更上层对实例化过程进行控制。

原理:执行元类的 元类的__new__方法和__init__方法用来实例化类对象,__call__ 方法用来对实例化的对象的实例即类的对象进行控制。__call__方法会调用实例类的__new__方法,用于创建对象。返回对象给__call__方法,然后调用类对象的__init__方法,用于对对象初始化。

原理:装饰器用来控制类调用__call__方法。

70. 装饰器的写法以及应用场景。

装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中。这里是一个例子来使用基于装饰器的授权:

return decorated # 该装饰器需相关配置才能运行,这里是截取代码展示应用

日志是装饰器运用的另一个亮点。这是个例子:

带参数的装饰器是典型的闭包函数

4.、在函数中嵌入装饰器

我们回到日志的例子,并创建一个包裹函数,能让我们指定一个用于输出的日志文件

# 现在将日志打到指定的logfile

# 现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串

# 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串

71. 异常处理写法以及如何主动抛出异常(应用场景)

72. 什么是面向对象的mro

对于定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。

为了实现继承,python会再MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。

MRO列表的构造是通过一个C3线性化算法来实现的。

合并所有父类的MRO列表遵循如下三条准则:

多个父类会根据它们再列表中的顺序被检查

如果对下一个类存在两个合法的选择,选择第一个父类

isinstance作用:来判断一个对象是否是一个已知的类型;

其第一个参数(object)为对象,第二个参数为类型名(int…)或类型名的一个列表((int,list,float)是一个列表)。其返回值为布尔型(True or flase)。

若对象的类型与参数二的类型相同则返回True。若参数二为一个元组,则若对象类型与元组中类型名之一相同即返回True。

74. json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?

自定义时间序列化转换器

75. json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?

在序列化时,中文汉字总是被转换为unicode码,在dumps函数中添加参数ensure_ascii=False即可解决。

76. 什么是断言?应用场景?

Python的assert是用来检查一个条件,如果它为真,就不做任何事。如果它为假,则会抛出AssertError并且包含错误信息。

2.运行时检查程序逻辑

with语句使用所谓的上下文管理器对代码块进行包装,允许上下文管理器实现一些设置和清理操作。

例如:文件可以作为上下文管理器使用,它们可以关闭自身作为清理的一部分。

78. 使用代码实现查看列举目录下的所有文件。

2:使用glob模块,可以设置文件过滤

3:通过os.path.walk递归遍历,可以访问子文件夹

当一个函数中出现yield关键字的时候,那么这个函数就是一个生成器。可以用for循环或者next()函数来迭代。yield 可以接收到外界传入的变量。

}

在ES6版本之前,JavaScript语言并没有传统面向对象语言的class写法,ES6发布之后,Babel迅速跟进,广大开发者也很快喜欢上ES6带来的新的编程体验。
当然,在这门“混乱”而又精妙的语言中,许多每天出现我们视野中的东西却常常被我们忽略。
对于ES6语法,考虑到浏览器的兼容性问题,我们还是要把代码转换为ES5版本运行。然而,之前的ES版本为什么能模仿ES6的诸多特性,比如class与继承,super,static?JavaScript又做了哪些改变以应对这些新角色?本文将对class实例构造,class继承关系,super关键字,static关键字的运行机制进行探索。
水平有限,文中若有引起困惑或错误之处,还望指出。

基本而言,ES6 class形式如下:

可知,constructor相当于以前在构造函数里的行为。而对于ES5构造函数而言,在被new调用的时候,大体上进行了下面四步:

  1. 判断Constructor的返回值,若返回值不为引用类型,则返回_this,否则返回改引用对象

所以,构造函数的实例会继承挂载在prototype上的方法,在ES6 calss中,我们这样写会把方法挂载在class的prototype:

在基于原型的语言,有以下四个特点:

  1. 一切皆为对象(js中除了对象还有基本类型,函数式第一等对象)
  2. 对象皆是从其他对象复制而来(在JS对象世界中,万物始于Object.prototype这颗蛋)
  3. 对象会记住它的原型(在JS中对象的__proto__属性指向它的原型)
  4. 调用对象本身没有的属性/方法时,对象会尝试委托它的原型

看到这,大家应该明白了,为什么挂载在Constructor.prototype的方法会被实例“继承”!

当箭头函数与class碰撞

ES6的箭头函数,一出身便深受众人喜爱,因为它解决了令人头疼的函数执行时动态this指向的“问题”(为什么加引号?因为有时候我们有时确实需要动态this带来的巨大便利)。箭头函数中this绑定在词法作用域,即它定义的地方:

有的童鞋可能会想到了,既然js中继承和this的关系这么大,在calss中采用词法绑定this的箭头函数,会有怎么样呢?

这种写法会与上文中写法有何区别?

我们在chrome环境下运行一下,看看这两种构造函数的prototype有何区别:

结合上文中关于原型的论述,仔细品味这两者的差别,最好手动尝试一下。


当我们谈论继承时,往往指两种:

  1. 对象实例继承自一个类(构造函数)

上文中我们探讨了第一种,现在,请把注意力转向第二种。

我们通过extends连接了两个class,标明他们是“父子关系”的类,子类中方法会屏蔽掉父类中同名方法,与Java中多态特性不同,这里的方法参数数量并不影响“是否同一种方法”的判定。

super可以让我们在子类中借用父类的属性和方法。

super来自何方?如何请到super这位大仙?

仔细想想,如果是这样(通过this找),考虑如下代码:

//以下代码删除了当前话题无关行
 
//此处就是对super.methodA()所做的转换,同样是硬绑定思路

注意属性与方法的差别:

箭头函数再袭super

结合前文中关于class内部箭头函数的谈论,有个问题不得不引起我们思考:class中的箭头函数里的super指向哪里?

似乎没什么意外。我们需要更新异步,把Parent的methodA方法改为箭头函数:

很抱歉,人见人恨得异常发生了:

如何把Child中的methodA改为普通方法函数呢?

以上几种结果产生的原因请结合前几章节细致品味,你会有所收获的。

简单来说,static关键词标志了一个挂载在class本身的属性或方法,我们可以通过ClassName.staticMethod访问到。

JS是门神奇的语言,神奇到很多人往往会用JS但是不会JS(...hh)。作为一门热门且不断改进中的语言,由于跟随时代和历史遗留等方面的因素,它有很多令人迷惑的地方。
在我们每天面对的一些特性中,我们很容易忽视其中机理。就算哪天觉得自己明白了,过一段时间可能又遇到别的问题,突然觉得自己懂得还是太少(还是太年轻)。然后刨根问底的搞明白,过一段时间可能又。。。或者研究JS的历程就是这样螺旋式的进步吧。
感谢Babel,她真的对我们理解JS一些特性的运行机理非常有用,因为Babel对JS吃的真的很透彻(...)。她对ES6的“翻译”,可以帮助我们对ES6新特性以及往前版本的JS的理解。
行文匆忙,难免有错漏之处,欢迎指出。
祝大家身体健康,BUG越来越少。

}

我要回帖

更多关于 java中的super()是调用什么函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信