001---基础部分
基础部分
In [15]:
# python的递归最大层数
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(1000)
print('可修改:',sys.getrecursionlimit())
In [16]:
# 用一行代码实现数值交换 a = 1 b = 2
a,b = 1,2
a,b = b,a
print(a,b)
In [18]:
# 列举布尔值为False的常见值
b = ['',0,[],(),{},False,None]
ls = [bool(i) for i in b]
print(ls)
In [20]:
# lambda 表达式及应用场景
# 匿名函数就是没有函数名,没有代码块的函数,主要和其他函数搭配使用
lambda x:x
lambda x,y:x+y
# 一般和内置函数搭配使用:map() reduce() sort()
Out[20]:
In [25]:
# pass的作用
if 1:
pass
# 代表过、不进行任何操作的意思,当代码块结构还没编写完时,可用pass来占位,(def class while if等)
In [30]:
# *args **kwargs
# 代表不定长参数 args 会把传入的参数变为一个元祖,kwargs会把传入的参数变为一个字典
def func(name,age,*args,**kwargs):
print(args)
print(kwargs)
func('子牙',21,1,'a','b',sex='男')
print('---------------')
# 如果你想把参数打包成一个列表,或者字典穿进去就要在前面加* 或者 ** 不然会是以一个整体传进去
func('子牙',21,[1,2,3],{'height':170,'weight':55})
print('---------------')
func('子牙',21,*[1,2,3],**{'height':170,'weight':55})
In [4]:
# is 和 == 的区别
# is 判断的不仅仅是值相等,还判断他们的内存地址是否相同,同 id() == 仅仅判断值相等
a = 1
b = 1
print(a,b)
print(a == b)
print(a is b)
print(id(a),id(b))
t1 = (1,2)
t2 = (1,2)
print(t1 is t2)
# 上面a is b为True是因为在python的解释权里面。简单的数据解释器里就一份。比如None、False、0、1、2、3、True等
n1 = 1234
n2 = 1234
print(n1 is n2)
print(n1 == n2)
a = True
b = True
print(a is b)
print(a == b)
print(id(a),id(b))
In [ ]:
# 简述Python的深浅拷贝以及应用场景
# 拷贝就是源对象数据的复制,占用不同的内存空间
# 对于不可变数据类型。数字和字符串。赋值、深浅拷贝无区别,拷贝前后都是引用同一块内存地址,所以拷贝具有减少内存空间的特点。
# 对于可变数据类型。列表、字典、元祖等可以相互嵌套,当构造出一些复杂的数据类型的时候
# 浅拷贝:只拷贝最外层的对象,也就是最外层的值一样。内存地址却不一样。而内层的值一样,内存地址也一样
# 深拷贝,它里面嵌套多少层,就会拷贝多少层出来,但是最底层的数字和字符串地址不变。
# 应用场景:数据入库、修改或者清洗的时候,拷贝源数据进行操作。防止对源数据造成修改,
# 拷贝就是在内存中重新开辟一个内存,数据一致,内存之间本身数据不共享,浅拷贝(数据半共享,拷贝出来的独立)、深拷贝(数据完全不共享,独立)
In [1]:
# Python的垃圾回收机制
# python采用的是引用计数机制为主、标记-清除和分代收集两种机制为辅
# 引用计数:跟踪和回收垃圾
# 标记-清除:解决容器对象可能产生循环引用的问题
# 分代回收:活的越长的对象、越不可能是垃圾。以空间换取时间来进一步提高垃圾回收的效率
In [ ]:
# python的可变类型和不可变类型
# 可变:列表、字典、集合
# 不可变:字符串、数字、元祖
In [4]:
# 求结果
v = dict.fromkeys(['k1','k2'],[])
print(v)
v['k1'].append(666)
# 因为k1 \k2 的value引用的是同一个列表的内存地址,所以,改变k1的值,k2也会变。
print(v)
v['k1'] = 777
# 对k1进行赋值操作,不会影响k2
print(v)
In [76]:
# 求res的值
def num():
# a = [lambda x:0,lambda x:x,lambda x:2*x,lambda x:3*x]
b = [lambda x:i*x for i in range(4)]
return b
res = []
for i in num():
res.append(i(2))
print(res)
# 这题有个误区
In [82]:
# filter、map、reduce的作用
# 这三个函数通常都是与lambda搭配使用,第一个参数通常为一个函数,第二个参数为一个可迭代对象
# map() 会把后面的可迭代对象,依次传给前面的lambda函数,
res = list(map(lambda name:name.title(),['python','java','linux']))
print(res)
# filter() 和 map()相似,但是如果入参的值为False ,则跳过,不进行处理
res = filter(lambda x:x,[0,1,2,3,None,'hello'])
print(list(res))
In [ ]:
#### 一行代码实现9*9的乘法表
print('\n'.join([''.join([('%s * %s = %-3s ')%(i,j,j*i) for j in range(1,i+1)]) for i in range(1,10)]))
In [38]:
# re模块的match和search的区别
import re
# match():尝试从头开始匹配,如果不是起始位置匹配成功,则返回None
s = 'jiangwei is a good good good boy'
res = re.match('jiangwei',s)
res1 = re.match('good',s)
print(res)
print(res1)
# search():尝试扫描整个字符串,返回第一个匹配成功的
s = 'jiangwei is a good good good boy'
res = re.search('good',s)
print(res)
In [ ]:
# 什么是正则的贪婪匹配
# 尝试尽可能多的匹配字符串:一般使用 * 代表贪婪匹配
# 非贪婪模式:一般在 * 后面加个 ?
# 默认会贪婪匹配
In [5]:
# 求结果
res= [ i % 2 for i in range(10)]
# range(10)得到一个可迭代对象 里面的每一个元素对2取余 [0,1,0,1,0,1,0,1,0,1]
print(res,type(res))
res = (i % 2 for i in range(10))
# 和上面一样,但是不是列表了,是一个生成器
print(res, type(res))
In [24]:
# 求结果
a = 1 or 2
print(a)
b = 1 and 2
print(b)
c = 1 < (2 == 2)
print(c)
d = 1 < 2 == 2
print(d)
In [32]:
# def func(a,b=[]) 这种写法有什么坑?
# 默认参数b是一个列表,肯定有问题,列表是可变的数据类型
def func1(a,b=[]):
b.append(a)
print(b)
func1(0)
func1(1)
func1(2)
# 第一次调用函数的时候,b实例化了一个列表。
# 第二次调用的时候,列表b里面已经有一个值了,所以,第二次调用时,虽然不传参,但是b并不是空列表。
# 所以尽量不要用可变类型作为参数
In [35]:
# 如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
# 字符串变列表、可以通过切割来实现
s = '1,2,3'
res = s.split(',')
print(res)
In [38]:
# 如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
# 本身的数据类型并没变、而是里面的元素的数据类型变了,可以用到列表生成式
ls = ['1','2','3']
res = [int(item) for item in ls]
print(res)
In [51]:
# 比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?
a = [1,2,3]
b = [(1),(2),(3)]
c = [(1,),(2,),(3,)]
# 第一种无区别 先来看看数据类型加括号是怎么一回事 虽然外面套了一层括号 但是是以括号内的数据类型的最小单位来声明
num = (1)
print(num)
ls = ([])
print(ls)
tp = (())
print(tp)
dic = ({})
print(dic,type(dic))
# 第二种有区别 括号内的元素加了逗号,其实是元祖。
print(a)
print(b)
print(c)
# 所以当你定义只有一个元素的元祖时。要加括号
In [52]:
# 如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?
print([num**2 for num in range(1,11)])
In [16]:
# 一行代码实现删除列表中重复的值 ?
ls = [1,1,2,3,0,0,4,5]
# 如果是简单的去重的话。用到集合就可以,有去重的效果,
print(list(set(ls)))
# 如果想保持原来的位置\
print(sorted(list(set(ls)),key=ls.index))
# 还有一个就是sote()函数,但是它是对原列表进行修改,而不是生成新列表
ls3 = list(set(ls))
ls3.sort(key=ls.index)
print(ls3)
In [18]:
# 如何在函数中设置一个全局变量 ?
n = 1
def func():
global n
n = 2
print(n)
func()
print(n)
In [ ]:
# logging模块的作用?以及应用场景?
# python内置的日志模块,用来记录一些用户的操作日志,包括服务器运行状态的信息。
In [19]:
# 请用代码简答实现stack 。
# stack是一种容器类数据类型。叫做栈,先进后出,就像我们往桌子上放一本本书,最后放的先拿出来。
# queen是一种与它相似的一种数据类型,叫做队列。但是是先进先出
# 实现栈,可以利用python自带的list来实现,list是一种线性数据结构。
class Stack(object):
def __init__(self):
self.stack = []
def pop(self):
# 出栈
if self.is_empty():
raise ValueError('栈空了')
return self.stack.pop()
def push(self,val):
# 进栈
self.stack.append(val)
def top(self):
# 查看最新元素:栈顶
return self.stack[-1]
def is_empty(self):
# 是否为空
return len(self.stack) == 0
def __iter__(self):
return iter(self.stack)
def __len__(self):
return len(self.stack)
def __str__(self):
return '%s'%self.stack
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print('%s出栈'%stack.pop())
stack.push(4)
print('栈的长度%s'%len(stack))
print(stack)
print('栈是否为空',stack.is_empty())
print('栈顶%s'%stack.top())
print('%s出栈'%stack.pop())
print('%s出栈'%stack.pop())
print('%s出栈'%stack.pop())
In [16]:
# 常见的字符串格式化有哪几种
# 第一种:占位符
name = 'Jzy'
age = 22
print('my name is %s,i am %d years old' % (name, age))
# 第二种format
# 通过变量
print('my name is {0},i am {1} years old '.format(name,age))
# 通过位置
data = ['Jzy',22]
print('my name is {0},i am {1} years old '.format(*data))
# 通过关键字
data = {'name':'Jzy','age':22}
print('my name is {name},i am {age} years old '.format(**data))
# 新特性
print(f'my name is {name},i am {age} years old')
In [ ]:
# 减速生成器、迭代器、可迭代对象以及应用场景
迭代器:
生成器:
可迭代对象:
In [ ]:
# 用python写一个二分查找
In [ ]:
# 谈谈你对闭包的理解
In [ ]:
# os和sys模块的作用
In [ ]:
# 如何生成一个随机数
In [ ]:
# 如何用python删除一个文件
In [ ]:
# 谈谈你对面向对象的理解
'''
在任何一门编程语言中,面向对象一般都具有封装、继承、多态三大特性。
封装:
- 将同类方法和属性封装到类中
- 将属性封装到对象中:__init__()
- 比如:定义一个人类,每一个人就是一个个对象。然后每个人都有跑步、睡觉等行为,就可以将这两个行为封装到人类这个类中。每个人都有姓名、年龄等特征。就可以封装到对象的__init__()方法中。
- 使用:自定义的分页、rest_framework源码中的request进行了封装
继承:
- 将多个类的同类方法和属性抽取到基类中,抽取共性。
- 解决了代码的冗余
多态:
- 一种事物的多态类型
- 鸭子类型,走起来像鸭子,叫起来像鸭子,那它就是鸭子。
- 不管对象是什么类型,只要有那个方法就行。
- 比如说,定义一个动物类和一个人类。它们都实现了跑步这个方法,就可以定义一个公共函数,把这两个类的对象当作参数传进去,参数.run()方法。对于这个参数来说,它具有多种形态。体现了python的多态性。
- python自带的也有体现,比如说len()方法。可以传字符串对象。列表对象。元祖对象。就可以计算出它的长度。
'''
In [ ]:
# Python中面向对象中的继承有什么特点
In [ ]:
# 面向对象深度优先和广度优先是什么?
In [ ]:
# 面向对象中super的作用
In [ ]:
# 是否使用过functools中的函数,其作用是什么?
In [ ]:
# 列举面向对象中带双下划线的特殊方法
In [24]:
# 如何判断是函数还是方法
# 以前我认为写在类里面的就是方法,写在类外面的就是函数,其实不是
# 应该根据调用者来判断
from types import FunctionType,MethodType
def func():
pass
class Foo(object):
def __init__(self):
pass
def func1(self):
pass
obj = Foo()
print(isinstance(func,FunctionType),type(func)) # 函数
print(isinstance(obj.func1,MethodType),type(obj.func1)) # 对象调用是方法
print(isinstance(Foo.func1,FunctionType),type(Foo.func1)) # 类调用却是函数
In [ ]:
# 静态方法和类方法区别
# 静态方法无论是对象还是类都可以直接调用:@staticmethod
# 类方法只能类调用,切第一个参数必须为类
In [ ]:
# 列举面向对象中的特殊成员以及应用场景
In [ ]:
# 1、2、3、4、5、能组成多少个互不相同且无重复的三位数
In [ ]:
# 什么是反射?以及应用场景
# 反射是根据字符串去映射对象中的方法或属性
# django的cbv中,self.dispath根据反射来获取请求的method从而进行不同的处理。
In [ ]:
# metaclass的作用?以及应用场景
In [ ]:
# 用尽量多的方法实现单例模式
# python有着纯天然的单例模式,导入多次相同模块或者包,都只有一个对象
# 使用装饰器
def singleton(cls):
_instance = {}
def inner(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return inner
@singleton
class A:
pass
a1 = A()
a2 = A()
print(id(a1))
print(id(a2))
# 使用__new__()
class A:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super(A, cls).__new__(cls)
return cls._instance
a1 = A()
a2 = A()
print(id(a1))
print(id(a2))
In [13]:
# 装饰器的写法,以及应用场景
def wraper(func):
"""
为被装饰函数加一个打印参数的值的功能
"""
def inner(*args,**kwargs):
print('这是函数的参数',args,kwargs)
return func(*args,**kwargs)
return inner
@wraper
def func(*args,**kwargs):
print('我被装饰了')
return 1
res = func(1,2,**{'name':'Jzy','age':22})
print(res)
# 装饰器本身就是遵循对外开放扩展,对内封闭不修改
In [ ]:
# 异常处理写法以及如何主动抛出异常
In [ ]:
# 什么是面向对象的mro
In [ ]:
# isinstance作用,以及应用场景
In [ ]:
# json序列化时,可以处理的数据类型有哪些,如何定制支持datetime类型
In [ ]:
# json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
In [ ]:
# 什么是断言,以及应用场景
In [ ]:
# 有用过with statement吗?它的好处是什么
In [ ]:
# 使用代码实现列举目录下的所有文件
In [ ]:
# 简述yield和yield from关键字