面试整理:Python基础

Python基础

 1. Python和其他语言有什么区别?

# python是解释型语言代码运行期间逐行翻译成目标机器码,下次执行时,要逐行解释

        # - 解释型:边解释边执行(python、PHP)
        # - python 弱类型
        # - 编译型:编译后再执行(C、Java、C#)

2. 你为什么要学Python?

# a. 因为python相对其他语言非常优雅简洁,有着丰富的第三方库,我感觉很方便、很强大;
# b. 还有就是,我感觉Python简单易学,生态圈庞大,例如:web开发、爬虫、人工智能等
# c. 而且未来发展趋势也很不错。


# 了解python的途径
        # a. 亲朋和学长的建议
        # b. 在我学Python之前,他们都是业内人士,对行业趋势比较了解

基本数据类型

3、常用数据类型&方法

可哈希:list dict set   
不可哈希:int str bool None tuple
# - 字符串 
    strip()去除   
   find()找不到返回-1 、index()找不到报错   
   split()分割  
   join()拼接    
    replace()分割  
   center()填充

# - 字典     
   pop() 删除   
  update()  
  clear()清空  
  get()  
  has_get()  
  dict.items()

# - 元组tuple  
    只读 按str索引方法去查

# - 列表     
   inset()按索引增加  
  extend()迭代增加  
  conut()  
  sort()排序  
  index() 
  rserver()反转

# - 集合   
    add()  
    update()  
    remove()  
    del()  
    pop()  
    clear()  
    交集$  
    并集|  
    差集-

# - collections  
    Python内建的一个集合模块,提供了许多有用的集合类。
  # Counter是一个简单的计数器,例如,统计字符出现的个数:
  # OrderedDict可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key:
  # deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
  # defaultdict使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:

函数

装饰器

4、什么是装饰器,在哪里用过?

# 能够在不修改原函数代码的基础上,在执行前后进行定制操作; 闭包函数的一种应用.
    - 能手写出来
    - 应用场景:
        - flask路由系统
        - flask befor_request
        - csrf
        - django 内置认证
        - django 的缓存
- 高阶函数
- 闭包
- 装饰器 
- functools.wraps(func)

5、写出一个装饰器

import functools

def warpper(func):
    @functools.wraps(func)   #不改变原函数属性
    def inner(*args,**kwargs):
        #执行函数前
        return func(*args,**kwargs)
        #执行函数后
    return inner

# 1. 执行wapper函数,并将被装饰的函数当做参数。 wapper(index)
# 2. 将第一步的返回值,重新赋值给  新index =  wapper(老index)
@warpper   #index=warpper(index)
def index(x):
    return x+100

6、为什么要用装饰器?

 

7、生成器

生成器:一个函数内部存在yield关键字(必问)
应用场景:
    - range()/xrange
        - py2:range(10000000),立即创建;xrange(10000000),是生成器
        - py3:range(10000000)生成器;

    - redis获取值
        - conn = Redis(......)
        - v=conn.hscan_iter() # 内部通过yield 来返回值

    - stark组件中
        - 前端调用后端的yield     

8、迭代器

迭代器:内部实现__next__方法,帮助我们向后一个一个取值.
可迭代对象: 一个类中内部实现__iter__方法,且返回一个迭代器

迭代器应用场景:
        - wtforms里面对form对象进行循环时,显示form中包含的所有字段
        - 列表\字典\元组
        总结: 如让一个对象可以被for 循环

9、闭包

# 内部函数含有对 外部作用域而非全局作用域名字 的引用,该内部函数称为闭包函数;
# 判断闭包函数的方法:__closure__,输出的__closure__有cell元素说明是闭包函数

def foo():
    m=3
    n=5
    def bar():
        a=4
        return m+n+a
    return bar
  
>>>bar =  foo()
>>>bar()
12

说明:
bar在foo函数的代码块中定义。我们称bar是foo的内部函数。

在bar的局部作用域中可以直接访问foo局部作用域中定义的m、n变量。
简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包。

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

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

#应用领域:延迟计算(原来我们是传参,现在我们是包起来)

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

10、偏函数

偏函数:
import functools
def func(a1, a2, a3):
    return a1 + a2 + a3

new_func = functools.partial(func, 11, 2)  #将11,2依次传入到func函数的前两个参数
print(new_func(3))

应用场景
falsk中取值时 通过localproxy 、偏函数、localstack、local

11、Python函数的传值方式是什么?

# Python参数传递采用“传对象引用”的方式。


如果函数收到的是一个可变对象(比如,字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。

如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值'来传递对象。    

参考:python函数中把列表(list)当参数时的"入坑"与"出坑"

12、匿名函数

匿名函数(lambda)在列表生成式和生成器中的应用示例

13、常见内置函数

map()函数接收两个参数,一个是函数,一个是可迭代对象,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
def mul(x):
    return x*x

n=[1,2,3,4,5]
res=list(map(mul,n))
print(res)  #[1, 4, 9, 16, 25]
map()
filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
def is_odd(x):
    return x % 2 == 1

v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17]))
print(v)  #[1, 7, 9, 17]
filter()
isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

isinstance() 与 type() 区别:

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

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

如果要判断两个类型是否相同推荐使用 isinstance()。
isinstance和type
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
>>>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)]
zip()
reduce() 函数会对参数序列中元素进行累积。

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

>>>def add(x, y) :            # 两数相加
...     return x + y
... 
>>> reduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5
15
>>> reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数
15
reduce()

面向对象

14、谈谈你对面向对象的认识?

封装

#封装:
其实就是将很多数据封装到一个对象中,类似于把很多东西放到一个箱子中,
如:一个函数如果好多参数,起始就可以把参数封装到一个对象再传递。
#在哪里用过:
    - django rest framework中的request对象。
    - flask中:ctx_context/app_context对象

继承

#继承:
如果多个类中有共同的方法,那么为了避免反复编写,就可以将方法提取到基类中,
让所有派生类去继承即可。
#在哪里用过?
    - 视图
    - 版本、认证、分页

多态

#多态
指基类的同一个方法在不同派生类中有着不同功能。python天生支持多态。
崇尚鸭子模型,只要会呱呱叫的就是鸭子。
def func(args):
  args.send()
class A:
    def send(self):
        print("A")
class B:
    def f(self):
        print("B")

def func(arg):
    arg.send()

obj = A()
func(obj)
多态示例

15、常用的面向对象方法(双下划线方法)

Flask LocalProxy 的定义几乎包含了所有双下划线方法

__getattr__
  CBV
  django配置文件
  wtforms中的Form()示例化中 将"_fields中的数据封装到From类中"

__mro__ 
 wtform中 FormMeta中继承类的优先级

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

__new__ 
 实例化但是没有给当前对象
 wtforms,字段实例化时返回:不是StringField,而是UnboundField
 est frawork many=Turn  中的序列化

__call__
 flask 请求的入口app.run()
 字段生成标签时:字段.__str__ => 字段.__call__ => 插件.__call__

__iter__ 
 循环对象是,自定义__iter__
 wtforms中BaseForm中循环所有字段时定义了__iter__

-metaclass
 作用:用于指定当前类使用哪个类来创建
 场景:在类创建之前定制操作
 示例:wtforms中,对字段进行排序。

16、对super的认识

super([type[, object-or-type]])
# 1.super函数返回的是一个代理对象,通过此对象可以调用所在类的父类或者兄弟类的方法,而不显示的指定父类或者兄弟类的类名。
# 2.引入super之后,不需要显示指定父类的类名,增强了程序的可维护性。
# 3.不带参数的super等效于super(类名,self),此种情况多用于单继承关系的子类中。

17、super工作原理

def super(cls, inst):
       mro = inst.__class__.mro()
       return mro[mro.index(cls) + 1]

# 其中cls 代表类,inst 代表实例,super函数做了两件事:
1. 获取实例对象inst的类的MRO列表
2. 查找cls在当前MRO列表中的index, 并返回它的下一个类,即mro[index + 1]
    

# 当使用 super(cls, inst) 时,Python 会在 inst 的 MRO 列表上搜索 cls的下一个类。可以看出,事实上super 函数和父类什么的没有实质性的关联。

# 示例:
class Base(object):
    def func1(self):
        print("Base.func")
class Foo(Base):
    def func1(self):
        print("Foo.func")
class Bar(object):
    def func(self):
        print("Bar.func")
class CC(Foo, Bar):
    def execute(self):
        super(CC, self).func()
obj = CC()
obj.execute()  # Bar.func

18、⾯向对象深度优先和广度优先是什么?

# Python的类可以继承多个类,Python的类如果继承了多个类,那么其寻找方法的方式有两种

# 当类是经典类时,多继承情况下,会按照深度优先方式查找

# 当类是新式类时,多继承情况下,会按照广度优先方式查找

# 简单点说就是:经典类是纵向查找,新式类是横向查找

# 经典类和新式类的区别就是,在声明类的时候,新式类需要加上object关键字。在python3中默认全是新式类

>>>> 面向对象封装思想小结

 

posted @ 2018-04-24 08:55  ZhuGaochao  阅读(153)  评论(0编辑  收藏  举报