Python面试题解析之Python基础篇

python面试题解析(python基础篇80题)

  1. 答:出于编程的喜好,以及行业自己的前瞻性,创造性,优越性,越是综合的科目越能检验一我的的能力,喜欢这种有挑战的事情。
  2. 答:跟随老师学习,以及本身查询资料,结合实战,进行输入输出以及纠正。
  3. 答:python是强类型加动态语言,自带有丰富的库,能够进行直接调用,无需重复造轮子,缺点是运行相同的程序,速度远慢于其它类型语言。
  4. 答:编译型语言是指在运行前先由编译器将高级语言代码编译为对应机器的cpu汇编指令集,再由汇编器汇编成目标机器码,生成可执行文件,而后最后运行生成的可执行文件。解释型在运行时由翻译器将高级语言代码翻译成易于执行的中间代码,并由解释器逐一将该中间代码解释成机器码并执行。

  5.答:Cpython,由C语言开发,在命令行下运行python就是启动Cpython。java

Ipython,基于Cpython之上的一个交互性解释器,执行方式与Cpython相同。python

PyPy,以执行速度为目标的解释器,采用JIT技术,对python代码进行动态编译,绝大多数代码能够在PyPy下运行。面试

Jpython,运行在java平台的python解释器,能够直接把python代码编译成java字节码执行。正则表达式

  6.答:8位(bit)=1个字节(byte),位是计算机内部数据存储的最小单位,字节是计算机中数据处理的基本单位,计算机中以字节位单位存储和解释信息,规定一个字节由8个二进制位构成。redis

  7.答:8bit = 1byte =1/1024kb = 1/ 1024^2mb = 1/1024^3GB算法

  8.答:缩进使用4个空格,或者IDE中以TAB键当作4个空格。django

全部行限制为最多79个字符编程

两个空白行围绕顶层函数和类定义json

核心代码应始终使用UTF-8,全部标识符使用纯ascii标识符,而且应尽量使用英文单词。flask

Import接口一般应该分开,导入始终放在文件的顶部,紧跟在任何模块注释和文档字符串以后,模块全局变量和常量以前。

  9.答:

v = int('0b1111011', 2)
print(v)

v1 = bin(18)
print(v1)
v2 = int('011', 8)
print(v2)
v3 = oct(30)
print(v3)
v4 = int('0x12', 16)
print(v4)
print(hex(87))

10.答:

a = "10.3.9.12"


def func(ip):
    Iplist = ip.split(".")  # ['10', '3', '9', '12']
    res = " "
    temp = []
    for i in Iplist:  # <class 'str'>
        i = int(i)  # <class 'int'>
        i = bin(i)[2:]  # <class 'str'>
        temp.append(i.rjust(8, "0"))  # 右对齐,向左填充数据
    res = res.join(temp)
    return res


b = "".join([" ".join(str(bin(int(i))[2:]).rjust(8, "0") for i in a.split("."))])
print(func(a))

11. 答:997层

12.答:1(布尔或:若是x是True,它返回x的值,不然它返回y的计算值。)               
3(x and y 布尔"与" - :
若是 x 为 False,x and y 返回 False,不然它返回 y 的计算值。)              

      0

      1

      1

      False

13.答:ascii编码是一个字节,unicode一般是2个字节,GBK则是第一个字节是大于127就固定表示这是一个汉字的开始。Utf-8是每次8个位传输数据,utf-16 就是每次16个位。

14.      答:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,可是很是晦涩难懂,也比较难编写,通常从业人员接触不到。

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

15.答: var = 1 if 条件成立else 2

16.答:1. 性能

  - Py3.x性能比Py2.5慢15%,但还有很大的提高空间。

2.编码

  - Py3.X源码文件默认使用utf-8编码

3. 语法

  - 去除print语句

  - 关键词加入as 和with,还有True,False,None

  - 删除了raw_input,用input代替

  - 新的metaclass语法

4. 字符串和字节串

  - 字符串只有str一种类型

5.数据类型

  - 只有一种整型——int

  - 新增了bytes类型

6.面向对象

  - 容器类和迭代器类被ABCs化,因此cellections模块里的类型比Py2.5多了不少

  - 迭代器的next()方法更名为__next__(),并增长内置函数next(),用以调用迭代器的__next__()方法

 

17.答: b, a = a,b

18.  答:int <= 32 位整数
long > 32 位整数

19. 答:二者的区别是xrange返回的是一个可迭代的对象,range返回的则是一个列表. 同时效率更高,更快。

  - 缘由是实现的时候使用了 yield(此为python2.x回答,python3已删除xrange)

20. 答:xreadlines = 返回一个生成器对象,

readlines =  遍历文件全部行

21.答:

//     alert(new Boolean(0));  //false

//     alert(new Boolean(-0)); // false

//     alert(new Boolean(null)); // false

//     alert(new Boolean(NaN)); // false

//     alert(new Boolean(undefined)); // false

//     alert(new Boolean("undefined")); // true

//     alert(new Boolean("")); // false

//     alert(new Boolean(false)); // false

//     alert(new Boolean("false")); // true

 

22. 答:

      列表:list

    - list.append(obj) # 在列表末尾添加新的对象

    - list.count(obj)  # 统计某个元素在列表中出现的次数

    - list.extend(seq) # 在列表末尾一次性追加另外一个序列中的多个值(用新列表扩展原来的列表)

    - list.index(obj)  # 从列表中找出某个值第一个匹配项的索引位置

    - list.insert(index, obj)# 将对象插入列表

    - list.pop(obj=list[-1]) # 移除列表中的一个元素(默认最后一个元素),而且返回该元素的值

    - list.remove(obj) # 移除列表中某个值的第一个匹配项

    - list.reverse()   # 反向列表中元素

    - list.sort([func])# 对原列表进行排序

    - list.clear()     # 清空列表

    - list.copy()      # 复制列表

字典:dict

    - popitem()    # 随机返回并删除字典中的一对键和值(通常删除末尾对)。

    - key in dict  # 若是键在字典dict里返回true,不然返回false

    - radiansdict.copy()   # 返回一个字典的浅复制

    - radiansdict.keys()   # 以列表返回一个字典全部的键

    - radiansdict.items()  # 以列表返回可遍历的(键, 值) 元组数组

    - radiansdict.clear()  # 删除字典内全部元素

    - radiansdict.values() # 以列表返回字典中的全部值

    - radiansdict.fromkeys()    # 建立一个新字典,以序列seq中元素作字典的键,val为字典全部键对应的初始值

    - radiansdict.update(dict2) # 把字典dict2的键/值对更新到dict里

    - radiansdict.get(key, default=None)        # 返回指定键的值,若是值不在字典中返回default值

    - radiansdict.setdefault(key, default=None) # 和get()相似, 但若是键不存在于字典中,将会添加键并将值设为default

    - pop(key[,default])   # 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。不然,返回default值。

字符串:str

    - upper()      # 转换字符串中的小写字母为大写。

    - title()      # 返回"标题化"的字符串,就是说全部单词都是以大写开始,其他字母均为小写(见 istitle())。

    - lower()      # 转换字符串中全部大写字符为小写。

    - rstrip()     # 删除字符串字符串末尾的空格.

    - lstrip()     # 截掉字符串左边的空格或指定字符。

    - max(str)     # 返回字符串 str 中最大的字母。

    - min(str)     # 返回字符串 str 中最小的字母。

    - join(seq)    # 以指定字符串做为分隔符,将 seq 中全部的元素(的字符串表示)合并为一个新的字符串

     ...

    MySlef

整数:int

    - bit_length()  # 查询以二进制表示一个数字的值所需的位数

    - int.from_bytes(bytes,byteorder)  # 返回给定字节数组所表示的整数。

    - int.to_bytes(length,byteorder)   # 返回表示整数的字节数组。

元组:tuple

    - len(tuple) # 计算元组元素个数。

    - max(tuple) # 返回元组中元素最大值。

    - min(tuple) # 返回元组中元素最小值。

    - tuple(seq) # 将列表转换为元组。

集合:set

    - set1 = set({1, 2, 'barry'}) # 建立集合

    - set2 = {1, 2, 'barry'}      # 建立集合

    - add  # 将元素添加到集合中。若是元素已经存在,这不起做用。

    - del set1  # 删除集合- update # 迭代增长

    - clear  # 删除此集合中的全部元素

    - remove # 删除一个元素

    - pop    # 随机删除一个元素

    - issubset    # 子集

    - issuperset  # 超集

    - union  # 并集。(| 或者 union)

    - difference # 差集。(- 或者 difference)

    - intersection  # 交集。(&  或者 intersection)

    - isdisjoint    # 若是两个集合有一个空交点,则返回True

    - intersection_update  # 用它本身和另外一个交集更新一个集合。

    - difference_update  # 删除另外一个集合中本集合所拥有的全部元素

    - symmetric_difference  # 反交集。(^ 或者 symmetric_difference)

浮点:float

    - is_integer # 若是浮点数是整数,则返回True

collections:Python内建的一个集合模块,提供了许多有用的集合类。

    - Counter     # 是一个简单的计数器,例如,统计字符出现的个数:

    - OrderedDict # 能够实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最先添加的Key:

    - deque       # 是为了高效实现插入和删除操做的双向列表,适合用于队列和栈:

    - defaultdict # 使用dict时,若是引用的Key不存在,就会抛出KeyError。若是但愿key不存在时,返回一个默认值,就能够用defaultdict:

 

23. 答:

my_lambda = lambda arg : arg + 1

匿名函数主要是和其它函数搭配使用,不须要显示指定函数名。

 

24. 答:

- 1. 不作任何事情,通常用作占位语句。

 - 2. pass是空语句,是为了保持程序结构的完整性。

25. 答:

位置参数(positional argument)

关键词参数(keyword argument)

  - *args表示任何多个无名参数,它本质是一个 tuple ;

  - **kwargs表示关键字参数,它本质上是一个 dict ;

  - 而且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前。

26. 答:

- is 比较的是两个实例对象是否是彻底相同,它们是否是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片彻底相同的叶子”,这个is正是这样的比较,

比较是否是同一片叶子(即比较的id是否相同,这id相似于人的身份证标识)。

  - == 比较的是两个对象的内容是否相等,即内存地址能够不同,内容同样就能够了。这里比较的并不是是同一片叶子,可能叶子的种类或者脉络相同就能够了。

       默认会调用对象的 __eq__()方法。

27.答:浅拷贝:只拷贝父对象,不会拷贝对象的内部的子对象(父对象不一样,子对象进行引用,ID相同)深拷贝:拷贝对象及其子对象(父, 子对象不一样) 因为深拷贝须要维护一个memo 用于记录已经拷贝的对象,因此这也是它比较慢的缘由

deepcopy优化版:

class FiveCardStudInfo(roomai.abstract.AbstractInfo):

    public_state = None

    person_state = None

    def __deepcopy__(self, memodict={}):

        info = FiveCardStudInfo()

        info.public_state = self.public_state.__deepcopy__()

        info.public_state = self.person_state.__deepcopy__()

        return info

 

 

28. 答:

引用计数

原理:当一个对象的引用被建立或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引用计数减1,当对象的引用计数减小为0时,就意味着对象已经再没有被使用了,能够将其内存释放掉。

优势:引用计数有一个很大的优势,即实时性,任何内存,一旦没有指向它的引用,就会被当即回收,而其余的垃圾收集技术必须在某种特殊条件下才能进行无效内存的回收。

缺点:可是它也有弱点,引用计数机制所带来的维护引用计数的额外操做与Python运行中所进行的内存分配和释放,引用赋值的次数是成正比的,这显然比其它那些垃圾收集技术所带来的额外操做只是与待回收的内存数量有关的效率要低。同时,引用技术还存在另一个很大的问题-循环引用,由于对象之间相互引用,每一个对象的引用都不会为0,因此这些对象所占用的内存始终都不会被释放掉。以下:

a = []

b = []

a.append(b)

b.append(a)

print a

[[[…]]]

print b

[[[…]]]

标记-清除

标记-清除只关注那些可能会产生循环引用的对象,显然,像是PyIntObject、PyStringObject这些不可变对象是不可能产生循环引用的,由于它们内部不可能持有其它对象的引用。Python中的循环引用老是发生在container对象之间,也就是可以在内部持有其它对象的对象,好比list、dict、class等等。这也使得该方法带来的开销只依赖于container对象的的数量 

原理:1. 寻找跟对象(root object)的集合做为垃圾检测动做的起点,跟对象也就是一些全局引用和函数栈中的引用,这些引用所指向的对象是不可被删除的;2. 从root object集合出发,沿着root object集合中的每个引用,若是可以到达某个对象,则说明这个对象是可达的,那么就不会被删除,这个过程就是垃圾检测阶段;3. 当检测阶段结束之后,全部的对象就分红可达和不可达两部分,全部的可达对象都进行保留,其它的不可达对象所占用的内存将会被回收,这就是垃圾回收阶段。(底层采用的是链表将这些集合的对象链接在一块儿)

缺点:标记和清除的过程效率不高。

分代回收

原理:将系统中的全部内存块根据其存活时间划分为不一样的集合,每个集合就成为一个“代”,Python默认定义了三代对象集合,垃圾收集的频率随着“代”的存活时间的增大而减少。也就是说,活得越长的对象,就越不多是垃圾,就应该减小对它的垃圾收集频率。那么如何来衡量这个存活时间:一般是利用几回垃圾收集动做来衡量,若是一个对象通过的垃圾收集次数越多,能够得出:该对象存活时间就越长。

 

 

29. 答:可变:

  - list,  - dict

不可变:

  -str,  - int,  - tuple,  - float,

30.答 {'k1': [666], 'k2': [666]}

{'k1': [666, 777], 'k2': [666, 777]}

31.答:[2, 2, 2, 2]

32. 答:map, filter, zip ,isinstance

33. 答:

map:遍历序列,对序列中每一个元素进行操做,最终获取新的序列。

  - 每一个元素增长100:

    - li = [11, 22, 33]

    - new_list = map(lambda a: a + 100, li)

  - 两个列表对应元素相加

    - li = [11, 22, 33]

    - sl = [1, 2, 3, 4]

    - new_list = map(lambda a, b: a + b, li, sl)

 

filter:对于序列中的元素进行筛选,最终获取符合条件的序列。

  - 获取列表中大于12的全部元素集合

    - li = [11, 22, 33]

    - new_list = filter(lambda arg: arg > 22, li)

    - # filter第一个参数为空,将获取原来序列

 

reduce:对于序列内全部元素进行累计操做。

  - 获取序列全部元素的和

    - li = [11, 22, 33]

    - result = reduce(lambda arg1, arg2: arg1 + arg2, li)

  - # reduce的第一个参数,函数必需要有两个参数

  - # reduce的第二个参数,要循环的序列

  - # reduce的第三个参数,初始值

 

34. 答:

print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))

 

35. 答:

      可经过pip install 模块名来进行联网安装。

      第三方模块,request,django, tornado,flask, redis等等。

 

36.      答:time&datetime模块,random模块,os模块,sys模块,shutil模块,json&pickle模块,shelve模块,xml模块,configParser模块,hashlib模块,subprocess模块,logging模块,re模块。

 

37. 答:

Match 从头开始匹配,search匹配包含。

 

38. 答:

      贪婪匹配:正则表达式通常趋向于最大长度匹配,也就是所谓的贪婪匹配

 

39. 答:a.    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

      b.<generator object <genexpr> at 0x012C4EA0>

 

40. 答:a. 1

      b.2

      c.False

      d.True

 

41. 答:函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list,第二次执行仍是用第一次执行的时候实例化的地址存储,因此三次执行的结果就是 [1, 1, 1] ,想每次执行只输出[1] ,默认参数应该设置为None。

 

42. 答:list("1,2,3".split(','))

 

43. 答:[int(x) for x in ['1','2','3']]

 

44.答:列表与列表内包含元祖,以及包含多个元祖。

 

45. 答:[i*i for i in range(1,11)]

 

46. 答:list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))

 

47. 答:1 声明法

在文件开头声明全局变量variable,

在具体函数中使用该变量时,须要事先声明 global variable,不然系统将该变量视为局部变量。

2模块法(推荐)

把全局变量定义在一个单独的模块中:
#gl.py
gl_1 = 'hello'
gl_2 = 'world'

在其它模块中使用
#a.py
import gl

def hello_world()
    print gl.gl_1, gl.gl_2

#b.py
import gl

def fun1()
    gl.gl_1 = 'Hello'
    gl.gl_2 = 'World'

 

48.答:记录日志,而且日志汇总包含的信息即有正常的程序访问日志,还可能有错误,警告等信息输出,应用场景主要有5个level。

DEBUG,INFO,WARNING,ERROR,CRITICAL。

 

49. 答:

1. Stack() 建立一个新的空栈

2. push(item) 添加一个新的元素item到栈顶

3. pop() 弹出栈顶元素

4. peek() 返回栈顶元素

5. is_empty() 判断栈是否为空

6. size() 返回栈的元素个数

 

class Stack(object):

    """栈"""

    def __init__(self):

         self.items = []

 

    def is_empty(self):

        """判断是否为空"""

        return self.items == []

 

    def push(self, item):

        """加入元素"""

        self.items.append(item)

 

    def pop(self):

        """弹出元素"""

        return self.items.pop()

 

    def peek(self):

        """返回栈顶元素"""

        return self.items[len(self.items)-1]

 

    def size(self):

        """返回栈的大小"""

        return len(self.items)

 

if __name__ == "__main__":

    stack = Stack()

    stack.push("hello")

    stack.push("world")

    stack.push("lcg")

    print stack.size()

    print stack.peek()

    print stack.pop()

    print stack.pop()

    print stack.pop()

 

 

50. 答:

Python的字符串格式化经常使用的有三种

  第一种:最方便的

  缺点:需一个个的格式化

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'))

 

51. 答:

容器:

   - 是一系列元素的集合,str、list、set、dict、file、sockets对象均可以看做是容器,容器均可以被迭代(用在for,while等语句中),所以他们被称为可迭代对象。

可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。

迭代器:

    - 持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__和__iter__方法,迭代器不会一次性把全部元素加载到内存,而是须要的时候才生成返回结果。

生成器:

    - 是一种特殊的迭代器,它的返回值不是经过return而是用yield。

装饰器

- 在不改变原函数代码的基础上,在执行先后进行定制操做

52. 答:

li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def search(someone, li):
    l = -1
    h = len(li)

    while l + 1 != h:
        m = int((l + h) / 2)
        if li[m] < someone:
            l = m
        else:
            h = m
    p = h
    if p >= len(li) or li[p] != someone:
        print("元素不存在")
    else:
        str = "元素索引为%d" % p
        print(str)


search(3, li)  # 元素索引为2

 

53. 答:def foo():

    m, n=3, 5

    def bar():

        a=4

        return m+n+a

    return bar

>>>bar =  foo()

>>>bar()

 

说明:

bar在foo函数的代码块中定义。咱们称bar是foo的内部函数。

 

在bar的局部做用域中能够直接访问foo局部做用域中定义的m、n变量。

简单的说,这种内部函数可使用外部函数变量的行为,就叫闭包。

 

- 闭包的意义与应用:延迟计算;

- 闭包的意义:      返回的函数对象,不只仅是一个函数对象,在该函数外还包裹了一层做用域,这使得,该函数不管在何处调用,优先使用本身外层包裹的做用域

 

#应用领域:延迟计算(原来咱们是传参,如今咱们是包起来)

 

装饰器就是闭包函数的一种应用场景

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

 

55. 答:使用random模块能够很容易生成随机字符串。

 

56. 答:os 模块中使用os.remove()来删除一个文件。

 

57. 答:- 简单描述:继承、封装、多态

- 系统描述:先对代码进行分类:按属性进行划分(file,DB),按功能划分,将同一类方法分为一类。将方法中共同的参数封装到对象中,把共用值封装到对象中。

面向对象的私有字段:

  - python中一切皆对象

  1. 封装:对数据的,对对象的封装。

  2. 继承:在类的基础上进行二次开发,经过函数super() 或者"基类名.方法名() "的方式实现这一目的的。

  3. 多态:同一个方法处于不一样对象中,能够产生不一样的结果

- 多态示例

# 鸭子模型

  class A:

      def send(self):

          pass

  class B:

      def send(self):

          pass

      def func(arg):

          arg.send()

          obj = B()

  func(obj)

 

58. 答:继承指的是类与类之间的关系,是一种“是”什么的关系,继承的功能之一就是解决代码重用问题,python中的继承可分为单继承和多继承。

 

59. 答:新式类跟经典类的差异主要是如下几点:

  1. 新式类对象能够直接经过__class__属性获取自身类型:type

  2. 继承搜索的顺序发生了改变,经典类多继承属性搜索顺序:

      - 先深刻继承树左侧,再返回,开始找右侧;

      - 新式类多继承属性搜索顺序: 先水平搜索,而后再向上移动。

        ps:(经典类深度优先,新式类广度优先)

  3. 新式类增长了__slots__内置属性, 能够把实例属性的种类锁定到__slots__规定的范围之中。

  4. 新式类增长了__getattribute__方法

 

Python 2.x中默认都是经典类,只有显式继承了object才是新式类

Python 3.x中默认都是新式类,没必要显式的继承object

 

60. 答:子类继承父类的方法,其继承顺序按照 __mro__来定义

 

61.答:

1. functools模块的引用

from functools import partial

2. functools模块的组成

  • partial(func, *args, **keywords)

经过封装,从新定义已有的函数,如增减参数、设置初始值或改变返回值。
该函数的返回partial对象,其中包含3个只读属性:

    • partial.func
    • partial.args
    • partial.keywords
    • @total_ordering

修饰class
实现多个比较操做方法,如__eq__, __lt__等

  • @lru_cache(maxsize=128, typed=False)

修饰方法,从新定义已有的函数
只存在于内存中

  • @singledispatch(default)

修饰方法
将函数转换为 single-dispatch generic function

  • @wraps(wrapped_func, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

调用update_wrapper()方法的简便实现

  • update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
  • reduce(function, iterable[, initializer])
  • cmp_to_key(func)

Python的functools模块用觉得可调用对象(callable objects)定义高阶函数或操做。简单地说,就是基于已有的函数定义新的函数。
所谓高阶函数,就是以函数做为输入参数,返回也是函数。

 

62. 答:- 双下划线:

  1. __getattr__:反射

     应用场景:

       - CBV

       - Django 配置文件

       - wtforms中的Form()实例化中将"_fields中的数据封装到Form类中"

  2. __mro__:定义解析类继承的顺序

     应用场景:wtforms中 FormMeta中继承的优先级

  3. __dict__:用来存储对象属性的一个字典,其键为属性名,值为属性的值

     - __dict__ 与 dir()的区别:

       1. dir()是一个函数,返回值是list

       2. dir用来寻找一个对象的全部属性值,包括__dict__中的属性,__dict__是dir()的子集

  4. __new__ :

     - 当你继承一些不可变的class时(好比int, str, tuple),提供给你一个自定义这些类的实例化过程的途径。

     - 实现自定义 metaclass

     应用场景:

       - wtforms 字段实例化时返回:不是StringField,而是UNboundField

       - rest_framework:many=Ture 中的序列化

       - 单例模式

  5. __call__:做用是使实例可以像函数同样被调用,同时不影响实例自己的生命周期,(__call__()不影响一个实例的构造和析构)

               可是__call__()能够用来改变实例的内部成员。

     __call__ 与 __init__的区别

     应用场景:

       - FLask 请求的入口app.run()

       - 字段生成标签时:字段.__str__ ==> 字段.__call__ ==> 插件.__call__

  6. __iter__:

     迭代器为何要必定实现__iter__方法(为何要返回自身)

     应用场景:wtforms中BaseForm中循环全部字段时自定义了__iter__方法

 

63. 答:from types import MethodType,FunctionType

 

class func(object):

    def foo(self):

        print(1)

Fun = func()

print(type(func.foo))

>>> <class 'function'>

 

print(type(Fun.foo))

>>> <class 'method'>

 

print(isinstance(func.foo,FunctionType))

>>> True

 

print(isinstance(Fun.foo,MethodType))

>>> True

 

经过类去调用函数foo时,不须要传self参数。此时foo为函数

若是经过对象Fun去调用foo时,对象自动传参self。而foo则是一个方法

 

64. 答:1、先是在语法上面的区别:
一、静态方法不须要传入self参数,类成员方法须要传入表明本类的cls参数;
二、静态方法是无妨访问实例变量和类变量的,类成员方法没法访问实例变量可是能够访问类变量
2、使用的区别:
因为静态方法没法访问类属性,实例属性,至关于一个相对独立的方法,跟类其实并无什么关系。这样说来,静态方法就是在类的做用域里的函数而已。
 
65. 答:1.
__doc__
描述类的信息


class Foo(object):
    # 单引号和双引号均可以 
    """这里描述类的信息"""

   
def func(self):
        pass


print(Foo.__doc__)


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


# __call__方法的执行是由对象加括号触发的,即:对象()或者 类()()
class Foo(object):
    def __call__(self, *args, **kwargs):
        print("running call", args, kwargs)


foo = Foo()
foo(1, 2, 3, name="UserPython")

Foo()(1, 2, 3, name="UserPython")

3.
__dict__
查看类或对象中的全部成员


class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


foo = Foo("UserPython", 17)

print(Foo.__dict__)  # 打印类里的全部属性,不包括实例属性
print(foo.__dict__)  # 打印全部实例属性,不包括类属性
显示的结果:

{‘__weakref__‘: < attribute ‘__weakref__‘ of ‘Foo‘ objects >, ‘__init__‘: < function
Foo.__init__
at
0x0000000000BB0730 >, ‘__dict__‘: < attribute ‘__dict__‘ of ‘Foo‘ objects >, ‘__module__‘: ‘__main__‘, ‘__doc__‘: None}
{‘name‘: ‘UserPython‘, ‘age‘: 17}

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


class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return "<obj:%s>" % self.name


foo = Foo("UserPython", 17)

print(foo)  # >>><obj:UserPython>
显示的效果为:

< obj:UserPython >

5.
__getitem__ 、 __setitem__ 、__delitem__
用于索引操做,如字典。分别表示获取、设置、删除数据


class Foo(object):

    def __getitem__(self, key):
        print("__getitem__", key)

    def __setitem__(self, key, value):
        print("__setitem__", key, value)

    def __delitem__(self, key):
        print("__delitem__", key)


foo = Foo()
foo["name"] = "UserPython"  # >>>__setitem__ name UserPython  触发__setitem__
foo["name"]  # >>>__getitem__ name  触发__getitem__
del foo["name"]  # >>>__delitem__ name  触发__delitem__


6.
__new__ 、__metaclass__


class Foo(object):

    def __init__(self, name):
        self.name = name


foo = Foo("UserPython")
‘‘‘‘‘
上述代码中,foo是经过Foo类实例化的对象,其实,不只foo是一个对象,Foo类自己也是一个对象,由于在Python中一切事物都是对象。
若是按照一切事物都是对象的理论:foo对象时经过执行Foo类的构造方法建立,那么Foo类对象应该也是经过执行某个类的构造方法建立。
‘‘‘

print(type(foo))
print(type(Foo))
# 因此,foo对象是Foo类的一个实例,Foo类对象是type类的一个实例,即:Foo类对象是经过type类的构造方法建立。那么,建立类就能够有两种方式了



# 普通方式
class Foo(object):
    def func(self):
        print("hello UserPython")


# 特殊方式
def func(self):
    print("hello %s" % self.name)


def __init__(self, name, age):  # 构造方法
    self.name = name
    self.age = age


# 建立了一个type类,而后用type类实例化了一个Foo类,因为Foo自己是一个类,因此Foo又实例化了一个对象foo
Foo = type(‘Foo‘, (object,), {"func": func, "__init__": __init__})

foo = Foo("UserPython", 19)

foo.func()

print(type(Foo))

 

66. 答:5*5*5 ,125个。

 

67. 答:反射主要是指程序能够访问,检测和修改它自己状态或行为的一种能力。

      Python面向对象中的反射,四个能够实现自省的函数。

      Hasattr()

      Getattr()

      Setattr()

      Delattr()

 

68.  答:metaclass是相似建立类的模板,全部的类都是经过他来create的(调用__new__),这使得你能够自由的控制

建立类的那个过程,实现你所须要的功能。1. 你能够自由的、动态的修改/增长/删除类的或者实例中的方法或者属性

2. 批量的对某些方法使用decorator,而不须要每次都在方法的上面加入@decorator_func

3. 当引入第三方库的时候,若是该库某些类须要patch的时候能够用metaclass

4. 能够用于序列化(参见yaml这个库的实现,我没怎么仔细看)

5. 提供接口注册,接口格式检查等

6. 自动委托(auto delegate)

 

69. 答:1. 文件导入:import方法

# 做为python的模块是自然的单例模式

class My_Singleton(object):

    def foo(self):

        pass

my_singleton = My_Singleton()

# to use

from mysingleton import my_singleton

my_singleton.foo()

 

 

2. 使用 __new__ 方法:

--------------------------------(1. # 没法支持多线程:)------------------------------

class Singleton(object):

    def __init__(self,name):

        self.name = name

    def __new__(cls, *args, **kwargs):

        if not hasattr(Singleton, "instance"):

            Singleton.instance = object.__new__(cls)

        return Singleton.instance

# to use :

obj0 = Singleton("alex")

obj1 = Singleton("alex")

obj2 = Singleton("alex")

 

----------------------------------(2. # 支持多线程:)---------------------------------

import threading

class Singleton(object):

    instance_lock = threading.Lock() # 为线程加互斥锁

    def __init__(self):

        pass

    def __new__(cls, *args, **kwargs):

        if not hasattr(Singleton, "instance"):

            with Singleton.instance_lock:

                if not hasattr(Singleton, "instance"):

                    Singleton.instance = object.__new__(cls)

                return Singleton.instance

        return Singleton.instance

def task():

    obj = Singleton()

    print(obj)

for i in range(5):

    t = threading.Thread(target=task)

    t.start()

 

 

3. 使用类实现

--------------------------------(1. # 没法支持多线程:)------------------------------

import threading

class Singleton(object):

    def __init__(self):

        pass

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            Singleton._instance = Singleton(*args, **kwargs)

    return Singleton._instance

# to use

obj = Singleton.instance()

obj2 = Singleton.instance()

print(id(obj), id(obj2))

----------------------------------(2. # 支持多线程:)---------------------------------

import time

import threading

class Singleton(object):

    _instance_lock = threading.Lock()

    def __init__(self):

        time.sleep(1)

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            with Singleton._instance_lock:

                if not hasattr(Singleton, "_instance"):

                    Singleton._instance = Singleton(*args, **kwargs)

        return Singleton._instance

# 第一次调用

def task(arg):

    obj = Singleton.instance()

    print(obj)

for i in range(10):

    t = threading.Thread(target=task,args=[i,])

    t.start()

# 第二次调用   

time.sleep(20)

obj = Singleton.instance()

obj2 = Singleton.instance()

print(id(obj, id(obj2)

 

 

4. 基于metaclass

--------------------------------------( 方法一 )--------------------------------------

# 建立对象

class SingletonType(type):

    def __call__(cls, *args, **kwargs):

        obj = super(SingletonType,cls).__call__(*args, **kwargs)   #type类帮建立__new__和__init__并返回

        return obj

class Foo(metaclass=SingletonType):

    def __init__(self,name):

        self.name = name

# to use

obj = Foo("alex")

print(id(obj1))

--------------------------------------( 方法二 )--------------------------------------

 

import threading

class SingletonType(type):

    _instance_lock = threading.Lock()

    def __call__(cls, *args, **kwargs):

        if not hasattr(cls, "_instance"):

            with SingletonType._instance_lock:

                if not hasattr(cls, "_instance"):

                    cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)

        return cls._instance

class Foo(metaclass=SingletonType):

    def __init__(self,name):

        self.name = name

# to use

obj1 = Foo('name')

obj2 = Foo('name')

print(id(obj1),id(obj2))

 

70. 答:def waper(func, x,y):

    print( int(x) + int(y) )

    @functools.wapper               # 保留原函数信息

    def inner(*args, **kwargs):

        """blabla的一些注释"""

        res = func(*args, **kwargs)

       return res

    return inner

 

@wapper(1,2)

def func(a):

    return a

func(123)     

 

71.答:try expect

 

72. mro即method resolution order,主要用于在多继承时判断调的属性的路径(来自于哪一个类)。

以前查看了不少资料,说mro是基于深度优先搜索算法的。但不彻底正确在Python2.3以前是基于此算法,但从Python2.3起应用了新算法:C3算法。

 

73.答:介绍:

    函数来判断一个对象是不是一个已知的类型,相似 type()。

语法:

    isinstance(object, classinfo)

      - object -- 实例对象。

      - classinfo -- 能够是直接或间接类名、基本类型或者由它们组成的元组。

返回值:

    若是对象的类型与参数二的类型(classinfo)相同则返回 True,不然返回 False。。

应用示例:

    >>>a = 2

    >>> isinstance (a,int)

    True

    >>> isinstance (a,str)

    False

    >>> isinstance (a,(str,int,list))    # 是元组中的一个返回 True

True

 

74.答:

class Solution(object):
    def twoSum(self, 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:
                return [buff_dict[nums[i]], i]
            else:
                buff_dict[target - nums[i]] = i

 

75.  答:

自定义时间序列化转换器

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))

# {"name": "alex", "data": "2018-05-18 19:52:05"}

76. 答:

import json

a=json.dumps({"ddf":"你好"},ensure_ascii=False)

print(a) #{"ddf": "你好"}

77. 答:

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

断言应该用于:

  • 防护型的编程
  • 运行时检查程序逻辑
  • 检查约定
  • 程序常量
  • 检查文档

78.答:with语句适用于对资源进行访问的场合,确保无论使用过程当中是否发生异常都会执行必要的“清理”操做,释放资源,好比文件使用后自动关闭、线程中锁的自动获取和释放等。

 

79. 答:PATH = ‘文件夹路径’ 
一、list_dir = os.listdir(PATH) 
二、list_dir = next(os.walk(PATH))[1]

 

80. 答:yield是python中定义为生成器函数,其本质是封装了  __iter__和__next__方法   的迭代器;

与return返回的区别:return只能返回一次值,函数就终止了,而yield能屡次返回值,每次返回都会将函数暂停,下一次next会从上一次暂停的位置继续执行;

相关文章
相关标签/搜索