python基础知识思维导图

           MyProcessOn

Python基础:

说说你眼中的python( 2 )

  1. 谈谈你对python和其他语言的区别

    1. python 中,变量是以内容为基准而不是像 c 中以变量名为基准;
    2. python 中,一个变量可以以多个名称访问;
    3. python 中,数字类型的值是不可变的;
    4. python 中,编译器会有一个小整数池的概念
  2. 谈谈你了了解的python种类以及相关特点
    Python的种类:
      - Cpython:使用 C 解释器来解释扩展名:.pyc C解释器 -> .pyc(字节码) -> 机器码 -> cpu 
      - Jpython:使用 Java 解释器 java 字节码->机器码 -> cpu 
      - ironpython:使用C#解释器 C# 字节码 -> 机器码 -> cpu
        PYPY:运行速度快,原理:解释器->字节码->编译成机器码->直接运行机器码,用户运行时直接使用机器码,所以运行速度快。
  3. 字节码和机器器码的关系和区别?
    - 机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。
    - 通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。
    - 字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
  4. 为什么要学python
    1. 编译型语言:一次性,将全部的程序编译成二进制文件,然后在运行。(c,c++ ,go)
        优点:运行速度快。
        缺点:开发效率低,不能跨平台。
    2. 解释型语言:当你的程序运行时,一行一行的解释,并运行。(python , PHP)
        优点:调试代码很方便,开发效率高,并且可以跨平台。
        缺点:运行速度慢。
    3. 我对程序的定义是人可以读懂,而机器刚好可以执行的一段代码,注重于代码的可读性。
       而Python的定位是“优雅”、“明确”、“简单”,用它编写的程序简单易懂,这与我当初的想法不谋而合
  5. pep8规范
    代码编排
      - 缩进。4个空格的缩进
      - 每行最大长度79,换行可以使用反斜杠
      - 类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。
    文档编排
      - 模块内容的顺序:按标准、三方和自己编写顺序依次排放,之间空一行
      - 不要在一句import中多个库
    空格的使用
    注释
    文档描述
    
  6. 123
  7. 123

py2与py3

  1. Python2和Python3的区别
    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__()方法
    
  2. range和xrange的区别
    两者的区别是xrange返回的是一个可迭代的对象,range返回的则是一个列表. 同时效率更高,更快。
      - 原因是实现的时候使用了 yield(此为python2.x回答,python3已删除xrange)
  3. Python3和Python2中 int 和 long 的区别
    
    int <= 32 位整数
    long > 32 位整数
  4. 文件操作时:xreadlines和readlines的区别
    
    xreadlines = 返回一个生成器对象,
    readlines =  遍历文件所有行
    
  5. 123
  6. 123

进制转换

  1. 二进制转换成十进制:v = "0b1111011"
    
    print(int(v,2)) # 可将任意进制数转换成十进制数(数字,这是多少进制)
    
  2. 十进制转换成二进制:v = 18
    
    print(bin(v))
    
  3. 八进制转换成十进制:v = "011"
    
    print(int(v,8)) # 可将任意进制数转换成十进制数(数字,这是多少进制)
    
  4. 十进制转换成八进制:v = 30
    
    print(oct(v))
    
  5. 十六进制转换成十进制:v = "0x12"
    
    print(int(v,16)) # 可将任意进制数转换成十进制数(数字,这是多少进制)
    
  6. 123

运算符 ( 8 )

  1. 各类运算符详解
  2. 各类运算符优先级
    
    运算符	                        描述
    **	                        指数 (最高优先级)
    ~ + -	                        按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
    * / % //	                乘,除,取模和取整除
    + -	                        加法减法
    >> <<                      右移,左移运算符
    &	                        位 'AND'
    ^ |	                        位运算符
    <= < > >=                   比较运算符
    <> == !=	                等于运算符
    = %= /= //= -= += *= **=	赋值运算符
    is is not	                身份运算符
    in not in	                成员运算符
    and or not	                逻辑运算符
    
  3. 求结果:2 & 5
    按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
    Python结果:0
    
  4. 求结果:2 ^ 5
    按位异或运算符:当两对应的二进位相异时,结果为1
    Python结果:7
  5. 求结果:1 or 3
    x or y
    布尔"或" :如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。
    Python结果:1
  6. 求结果:1 and 3
    x and y
    布尔"与" - :
    如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。
    python结果:>1
    
  7. 求结果:0 and 2 and 1
    Python结果: 0
  8. 求结果:0 and 2 or 1
    Python结果: 1
  9. 求结果:0 and 2 or 1 or 4
    Python结果:1
  10. 求结果:0 or False and 1
    Python结果:False
  11. 用⼀行代码实现数值交换: a = 1 b = 2
    b,a = a,b
  12. 123

数据结构( 2 )

  1. 基本的数据类型和方法都有哪些
    列表: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:
    
  2. 可变与不可变类型

    可变:
      - list,  - dict 
    不可变:
      -str,  - int,  - tuple,  - float, 
    
  3. 常⽤字符串格式化有哪些?
    
    1.占位符%
    %d 表示那个位置是整数;%f 表示浮点数;%s 表示字符串
      - print('Hello,%s' % 'Python')
      - print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:Hello,666Python10.00
    2.format
      - print('{k} is {v}'.format(k='python', v='easy'))  # 通过关键字
      - print('{0} is {1}'.format('python', 'easy'))      # 通过关键字
    
  4. 常用字符串格式化有哪些?
    
    - 0
    - ""
    - []
    - {}
    - (,)
    - None
    
  5. *Python2和Python3有差吗
    
    Python2和Python3有差吗
    
  6. Python2和Python3有差吗
    
    is和==的区别
    
  7. 123
  8. 123
  9. 123
  10. 123
  11. 123
  12. 123

函数( 9 )

  1. 函数参数传递的是什么? 引用、内存地址
    # 默认参数尽量避免使用可变数据类型
    # 默认参数只会被执行一次:第一次调用函数时,默认参数被初始化为【】,以后每次调用时都会使用已经初始化的【】。
    >>> def func(a,a1 = []):  #默认参数
    ...     a1.append(a)
    ...     print(a1)
    
    >>> func()
    [1]
    >>> func()
    [1, 1]
    >>> func()
    [1, 1, 1]
    >>> func()
    [1, 1, 1, 1]
  2. 闭包函数
    def foo():
        m, n=3, 5
        def bar():
            a=4
            return m+n+a
        return bar
    >>>bar =  foo()
    >>>bar()
    12
    
    说明:
    bar在foo函数的代码块中定义。我们称bar是foo的内部函数。
    在bar的局部作用域中可以直接访问foo局部作用域中定义的m、n变量。 简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包。 - 闭包的意义与应用: 延迟计算; - 闭包的意义: 返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域 #应用领域:延迟计算(原来我们是传参,现在我们是包起来) 装饰器就是闭包函数的一种应用场景
  3. 谈谈你对闭包的理解?
    
    说明:
    bar在foo函数的代码块中定义。我们称bar是foo的内部函数。
    
    在bar的局部作用域中可以直接访问foo局部作用域中定义的m、n变量。
    简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包。
    
    闭包的意义与应用:
    # 装饰器就是闭包函数的一种应用场景
    # 闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
    # 应用领域:延迟计算(原来我们是传参,现在我们是包起来)
        from urllib.request import urlopen
        def index(url):
            def get():
                return urlopen(url).read()
            return get
    
        baidu=index('http://www.baidu.com')
        print(baidu().decode('utf-8'))
    
  4. 必会内置函数 - map
    介绍:
        会根据提供的函数对指定序列做映射。
        第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
    语法:
        map(function, iterable, ...)
          - function --  函数,有两个参数
          - iterable  --  一个或多个序列
    应用示例:
    >>>def square(x) :            # 计算平方数
    ...     return x ** 2
    ... 
    >>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
    [1, 4, 9, 16, 25]
    >>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
    [1, 4, 9, 16, 25]
     
    # 提供了两个列表,对相同位置的列表数据进行相加
    >>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
    [3, 7, 11, 15, 19]
  5. 必会内置函数 - filter
    介绍:
        函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
        该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
    语法:
        filter(function, iterable)
          - function -- 判断函数。
          - iterable -- 可迭代对象。
    应用示例1:过滤出列表中的所有奇数:
        def is_odd(n):
            return n % 2 == 1
        newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
            print(newlist)
        >>>[1, 3, 5, 7, 9]
    应用示例2:过滤出1~100中平方根是整数的数
        import math
        def is_sqr(x):
            return math.sqrt(x) % 1 == 0
        newlist = filter(is_sqr, range(1, 101))
        print(newlist)
        >>>[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    应用示例3:filter相较于py2的区别
        python2中返回的是过滤后的列表, 而python3中返回到是一个filter类
        filter类实现了__iter__和__next__方法, 可以看成是一个迭代器, 有惰性运算的特性, 相对python2提升了性能, 可以节约内存。
        a = filter(lambda x: x % 2 == 0, range(10))
        print(a)
        >>><filter object at 0x000001CC57668518>
    
  6. 必会内置函数 - zip
    介绍:
        函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
    如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
    语法:
        zip([iterable, ...])
          - iterabl -- 一个或多个迭代器;
    返回值:
        - 返回元组列表。
    应用示例:
        >>>a = [1,2,3]
        >>> b = [4,5,6]
        >>> c = [4,5,6,7,8]
        >>> zipped = zip(a,b)     # 打包为元组的列表
        [(1, 4), (2, 5), (3, 6)]
        >>> zip(a,c)              # 元素个数与最短的列表一致
        [(1, 4), (2, 5), (3, 6)]
        >>> zip(*zipped)          # 与 zip 相反,可理解为解压,返回二维矩阵式
        [(1, 2, 3), (4, 5, 6)]
  7. 必会内置函数 - isinstance
    介绍:
        函数来判断一个对象是否是一个已知的类型,类似 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
    
  8. isinstance() 与 type()的区别
    介绍
    1. type() 不会认为子类是一种父类类型,不考虑继承关系。
    2. isinstance() 会认为子类是一种父类类型,考虑继承关系。
    # 如果要判断两个类型是否相同推荐使用 isinstance()。
    示例:
        class A:
            pass
        class B(A):
            pass
    
        isinstance(A(), A)    # returns True
        type(A()) == A        # returns True
        isinstance(B(), A)    # returns True
        type(B()) == A        # returns False
    
  9. pass的作用
     - 1. 不做任何事情,一般用做占位语句。
     - 2. pass是空语句,是为了保持程序结构的完整性。
    
  10. *args和**kwarg的作用
    位置参数(positional argument) 
    关键词参数(keyword argument)
      - *args表示任何多个无名参数,它本质是一个 tuple ; 
      - **kwargs表示关键字参数,它本质上是一个 dict ;
      - 并且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前。
    
  11. is和==的区别
    
      - is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片完全相同的叶子”,这个is正是这样的比较,
    比较是不是同一片叶子(即比较的id是否相同,这id类似于人的身份证标识)。 - == 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。 默认会调用对象的 __eq__()方法。
  12. 123
  13. 123
  14. 123

函数的应用

  1. ⼀⾏代码实现9*9乘法表
    print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))
    
  2. 如何实现 “1,2,3” 变成 [‘1’,’2’,’3’]
    
     - list("1,2,3".split(','))
    
  3. 如何实现[‘1’,’2’,’3’]变成[1,2,3]
    
    [int(x) for x in ['1','2','3']]
    
  4. 如何⽤⼀⾏代码⽣成[1,4,9,16,25,36,49,64,81,100]
    
    [i*i for i in range(1,11)]
    
  5. ⼀行代码实现删除列表中重复的值
    
    list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))
    
  6. 请编写一个函数实现将IP地址转换成一个整数
    如 10.3.9.12 转换规则为:
    10 00001010
    3   00000011
    9   00001001
    12 00001100
    再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?

    
    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))
    
    - "00001010 00000011 00001001 00001100"
    
  7. 用Python实现⼀个⼆分查找的函数 二分查找算法:
            简单的说,就是将一个列表先排序好,比如按照从小到大的顺序排列好,当给定一个数据,比如3,查找3在列表中的位置时,可以先找到列表中间的数li[middle]和3进行比较,当它比3小时,那么3一定是在列表的右边,反之,则3在列表的左边,比如它比3小,则下次就可以只比较[middle+1, end]的数,继续使用二分法,将它一分为二,直到找到3这个数返回或者列表全部遍历完成(3不在列表中)
            优点:效率高,时间复杂度为O(logN);
            缺点:数据要是有序的,顺序存储。
    
    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
    
  8. 1
  9. 1
  10. 1
  11. 1
  12. 1
  13. 1
  14. 请⽤代码简答实现stack
    
    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()
    
  15. 内置函数:map、reduce、filter的用法和区别
    
    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的第三个参数,初始值
    

函数的骚操作( 8 )

  1. 手写:三元运算符
    >>> val = "aaa" if 1==1 else "bbb"
    >>> val
    'aaa'
    >>>
  2. 手写:lambda表达式
    my_lambda = lambda arg : arg + 1
  3. 手写:列表推导式
    def func(x):
        return x+1
    
    variable = [ func  for num in range(10) if num == 2]
      func:        # 列表生成元素表达式,可以是有返回值的函数或者 lambda 函数。
      for num in range(10):  # 迭代 range(10) 将 num 传入 func 表达式中。
      if num == 2: # 根据条件过滤哪些值可以。
  4. 手写:列表推导式 + lambda表达式 :# 一行代码写出30以内所有能被3整除的数的平方:
    
    # 错误示例:不能使用列表生成式
        a = [lambda :i*i for i in range(31) if i%3 is 0]
    # 错误调用方式: # 每次只会返回最后一个被循环的range(30)!
        >>>a
        [. at 0x000002C97... ,>> a[0]
        . at 0x000002C977B96BF8>
        >>> a[0]()
        900
    # 正确示例:使用生成器迭代执行   # 注意括号!
        a = (lambda :i*i for i in range(31) if i%3 is 0) 
    # 调用方式:
    >>> a.__iter__
    <method-wrapper '__iter__' of generator object at 0x000002C977AF5938>
    >>> a.__iter__()
     at 0x000002C977AF5938>
    >>> a.__iter__().__next__
    <method-wrapper '__next__' of generator object at 0x000002C977AF5938>
    >>> a.__iter__().__next__()
    . at 0x000002C977B8CF28>
    >>> a.__iter__().__next__()()
    9
  5. 手写字典推导式
    # 推导式示例:
    >>> mcase = {'a': 10, 'b': 34}
    >>> mcase_frequency = {mcase[k]: k for k in mcase}
    >>> print(mcase_frequency)
    {10: 'a', 34: 'b'}
  6. 手写:字典推导式:合并大小写对应的value值,将k统一成小写
    #   _._
    >>> mcase = {'a': 10, b': 34, 'A': 7, 'Z': 3}
    >>> mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()}
    >>> print(mcase_frequency)
    {'a': 17, 'b': 34, 'z': 3}
  7. 手写:集合推导式
    # 集合推导式示例
    >>> squared = {x**2 for x in [ i for i in range(-5,10) ]}
    >>> print(squared)
    {1, 4}
  8. 列表推导式list comprehension和生成器的优劣

    1. 列表推导式是将所有的值一次性加载到内存中
    2. 生成器是将列表推导式的[]改成(),不会将所有的值一次性加载到内存中,延迟计算,一次返回一个结果,
       它不会一次生成所有的结果,这对大数据量处理,非常有用
    # 生成器函数: 一个函数中包含了yield关键词,那么这个函数就不是普通的函数,是一个生成器函数
    # 调用生成器函数,不会立马执行该函数里面的代码, 而是会返回一个 生成器对象

python三神器( 7 )

  1. 生成器、迭代器、装饰器、可迭代对象的区别
    容器:
       - 是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象。
    可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。
    迭代器:
        - 持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__和__iter__方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。
    生成器:
        - 是一种特殊的迭代器,它的返回值不是通过return而是用yield。
    装饰器
        - 在不改变原函数代码的基础上,在执行前后进行定制操作
    
  2. 生成器
    - 生成器,一个函数内部存在yield关键字;v = 函数()。
      应用场景:
        - range/xrange
        - py2: range(100000000),立即创建;xrange(100000000)生成器;
        - py3: range(100000000)生成器;
        - redis获取值
    	conn = Redis(...)
    	def hscan_iter(self, name, match=None, count=None):
    	"""
    	Make an iterator using the HSCAN command so that the client doesn't
    	need to remember the cursor position.
            ``match`` allows for filtering the keys by pattern
            ``count`` allows for hint the minimum number of returns
    	"""
            cursor = '0'
            while cursor != 0:
                # 去redis中获取数据:12
                # cursor,下一次取的位置
                # data:本地获取的12条数数据
                cursor, data = self.hscan(name, cursor=cursor, match=match, count=count)
                for item in data.items():
                    yield item
    
  3. 迭代器
    - 迭代器,内部实现__next__方法,帮助我们向后一个一个取值。
    
  4. 可迭代对象
    可迭代对象介绍
      - 一个类内部实现 __iter__ 方法且返回一个迭代器
          - 实例:
            class Foo(object):
                def __iter__(self):
                    return iter([11,22,33,44])
            obj = Foo()
      - 应用场景:
          - wtform中对form对象进行循环时,显示form中包含的所有字段。
          - 列表、字典、元组
    
  5. 什么是装饰器
    装饰器介绍
      - 在不改变原函数代码的基础上,在执行前后进行定制操作
      - 手写
      - 应用场景:
        - Flask : 路由、before_request、after_request
        - Django: csrf、缓存、内置用户登录认证
        - functools:缓存、warper
    
  6. 手写一个装饰器
    def waper(func):
        def inner(*args, **kwargs):
            res = func(*args, **kwargs)
           return res
        return inner
  7. 带参数的装饰器
    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)

面向对象 ( 10 )

  1. 谈谈你对面向对象的认识
    - 简单描述 :继承、封装、多态 
    - 系统描述 :先对代码进行分类:按属性进行划分(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)
  2. 你知道哪些双下划线方法
    - 双下划线:
      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__方法
  3. metaclass的作用
    - 作用:用于指定当前类事业那个类来创建 - 场景:在类创建之前定制的操作 示例:wtforms中对字段进行排序
  4. super的作用:

    子类继承父类的方法,其继承顺序按照 __mro__来定义
  5. 新式类与经典类的区别
    新式类跟经典类的差别主要是以下几点:
      1. 新式类对象可以直接通过__class__属性获取自身类型:type
      2. 继承搜索的顺序发生了改变,经典类多继承属性搜索顺序 :
          - 先深入继承树左侧,再返回,开始找右侧;
          - 新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动。
            ps:(经典类深度优先,新式类广度优先)
      3. 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。
      4. 新式类增加了__getattribute__方法
    
    Python 2.x中默认都是经典类,只有显式继承了object才是新式类
    Python 3.x中默认都是新式类,不必显式的继承object
  6. 深度优先和广度优先是什么
    python的类可以继承多个类,python的类如果继承了多个类,那么其寻找的方法有两种:
      - 当类是经典类时:多继承情况下,会按照深度优先的方式查找
      - 当类是新式类时:多继承情况下,会按照广度优先的方式查找
    简单点说就是:经典类是纵向查找,新式类是横向查找
  7. 什么是函数什么是方法?
    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则是一个方法
  8. 手写三个使用不同方法实现的单例模式

    单例模式:一个类只能有一个实例化对象
    应用场景:Django中的admin组件中admin.site()就是由单例模式创建的,其中封装了所有的表对象

    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))
    
  9. __new__, __init__的区别

    1. __new__是一个静态方法,而__init__是一个实例方法.
    2. __new__方法会返回一个创建的实例,而__init__什么都不返回.
    3. 只有在__new__返回一个cls的实例时后面的__init__才能被调用.
    4. 当创建一个新实例时调用__new__,初始化一个实例时用__init__.
    5. 继承自object的新式类才有__new__
    6. __new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
    7. __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,
      可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例
    8. __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
    9. 如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,
    10. 如果是其他类的类名,;那么实际创建返回的就是其他类的实例,其实就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。

    new与init的关系:

        1. new优于init加载执行

        2. 只能通过重写new方法来自定义不可变的类对象:(int,str,tuple),--->init方法不行

        3. 通过new方法可以实现单例模式

    lass Singleton(object):

        def __new__(cls):

            # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象

            if not hasattr(cls, 'instance'):

                cls.instance = super(Singleton, cls).__new__(cls)

            return cls.instance

    obj1 = Singleton()

    obj2 = Singleton()

    obj1.attr1 = 'value1'

    print obj1.attr1, obj2.attr1

    print obj1 is obj2

  10. 知道有哪些类的双下划线方法,并说明作用,返回值? https://www.zybuluo.com/kingwhite/note/136247
  11. 面向对象中super的作用?
    用于执行子类继承基类的方法
    
  12. 123
  13. 123
  14. 123

模块 ( 26 )

  1. 你的常用模块都有哪些 ( 1 )

    copy : 用于深浅拷贝
    os :与操作系统交互的一个接口 比如用来处理文件和目录
    random :随机模块
    sys:负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
    json:序列化
    re : 正则模块
    logging : 日志模块
    requests: 爬取数据
    timeit :
    subprocess:与OS模块相同,区别与异步提交命令不等待输出。与OS模块的区别

copy模块 ( 1 )

  1. 浅拷贝与深拷贝的实现方式及区别,如果你来设计Deepcopy,如何实现
    浅拷贝:只拷贝父对象,不会拷贝对象的内部的子对象(父对象不同,子对象进行引用,ID相同)
    >>> a = [1,[1,3],3]
    >>> import copy
    >>> b = copy.copy(a)
    >>> b
    [1, [1, 3], 3]
    >>> a[1].append(3)
    >>> b
    [1, [1, 3, 3], 3]
    <>>> a
    [1, [1, 3, 3], 3]
    深拷贝:拷贝对象及其子对象(父, 子对象不同)
    >>> a = [1,[1,2],3]
    >>> import copy
    >>> b = copy.deepcopy(a)
    >>> a[1].append(3)
    >>> b
    [1, [1, 2], 3]
    >>> a
    [1, [1, 2, 3], 3]

    如何进行实现:

    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

     由于深拷贝需要维护一个 memo 用于记录已经拷贝的对象,所以这也是它比较慢的原因

OS模块 ( 3 )

  1. 你知道哪些OS模块的方法
    os.remove(‘path/filename’)  # 删除文件
    os.rename(oldname, newname) # 重命名文件
    os.walk()   # 生成目录树下的所有文件名
    os.chdir('dirname') # 改变目录
    os.getcwd() # 取得当前工作目录
    os.path.getsize()   # 返回文件大小
    
  2. 创建、删除文件

    1. # 创建一个文件
    2. open("chao.txt","w",encoding="utf-8")
    3. import os
      #删除文件
    4. os.remove("chao.txt")
    
  3. 给出路径找文件

    
    --------------------------------( 方法一 )------------------------------
    使用os.walk:
    file-- 是你所要便利的目录的地址, 返回的是一个三元组(root,dirs,files)。
    
    root 所指的是当前正在遍历的这个文件夹的本身的地址
    dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)
    files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)
    def open_2(file):
    
        for root, dirs , files in os.walk(file):
            print("ss",files)
            for filename in files:
                print(os.path.abspath(os.path.join(root, filename)))   #返回绝对路径
    
    open_2("F:\搜索")
    
    
    --------------------------------( 方法二 )------------------------------
    import os
    def open(files):
    
        for dir_file in os.listdir(files):
            # print("ss",dir_file)   #递归获取所有文件夹和文件
            files_dir_file = os.path.join(files, dir_file) 
    
            if os.path.isdir(files_dir_file):  #是不是文件夹
                open(files_dir_file)
            else:
                print(files_dir_file)
    
    open("F:\搜索")
    
    并将下面的所有文件内容写入到一个文件中
    def open_2(file):
        for root, dirs , files in os.walk(file):
            for filename in files:
                with open(os.path.abspath(os.path.join(root, filename)), "r") as f:
                    for i in f.readlines():
                        print(i)
                        with open("./cao.txt","a",encoding="utf-8") as f2:
                            f2.write(i)
                            f2.write("\n")
    open_2("F:\搜索")
  4. 使用python打印路径下的所有文件
    
    # 方法一:(面试要求不使用os.walk)
    def print_directory_contents(sPath):
        import os
    
        for sChild in os.listdir(sPath):
            sChildPath = os.path.join(sPath, sChild)
            if os.path.isdir(sChildPath):
                print_directory_contents(sChildPath)
            else:
                print(sChildPath)
                
    # 方法二:(使用os.walk)
    def print_directory_contents(sPath):
        import os
        for root, _, filenames in os.walk(sPath):
            for filename in filenames:
                print(os.path.abspath(os.path.join(root, filename)))
    
    print_directory_contents('.')
    
    
  5. 如何使⽤python删除⼀个⽂件

    
    import os
    file = r'D:\test.txt'
    if os.path.exists(file):
        os.remove(file)
        print('delete success')
    else:
        print('no such file:%s' % file)
    
  6. 123

random模块

  • 如何⽣成⼀个随机数?
    import random
     
    print(random.random())          # 用于生成一个0到1的随机符点数: 0 <= n < 1.0
    print(random.randint(1, 1000))  # 用于生成一个指定范围内的整数
    
  • 123
  • 123

co

re模块 ( 4 )

  1. re模块的基本方法:
    .     匹配除换行符以外的任意字符
    \w    匹配字母或数字或下划线
    \s    匹配任意的空白符
    \d    匹配数字
    \n    匹配一个换行符
    \t    匹配一个制表符
    \b    匹配一个单词的结尾
    ^     匹配字符串的开始
    $     匹配字符串的结尾
    \W    
    匹配非字母或数字或下划线
    \D    
    匹配非数字
    \S    
    匹配非空白符
    a|b    
    匹配字符a或字符b
    ()    
    匹配括号内的表达式,也表示一个组
    [...]    
    匹配字符组中的字符
    [^...]    
    匹配除了字符组中字符的所有字符
     
    
    用法说明
    *    重复零次或更多次
    +    重复一次或更多次
    ?    重复零次或一次
    {n}    重复n次
    {n,}    重复n次或更多次
    {n,m}    重复n到m次
    View Code

相关文章: