41、def func(a,b=[]) 这种写法有什么坑?
Pycharm的语法警告:
Default argument value is mutable less... (Ctrl+F1)
This inspection detects when a mutable value as list or dictionary is detected in a default value for an argument.
Default argument values are evaluated only once at function definition time, which means that
modifying the default value of the argument will affect all subsequent calls of the function
最后一句的翻译:这意味着修改参数的默认值将影响函数的所有后续调用
网友解释:
b=[] 不是空的意思 就是默认创建了一个长度为0的list 这个在定义函数的时候就创建了
又因为创建的b是一个变量 而且是不可变的对象
也就是始终指向同一地址 所以每次调用函数得到的b都会改变
所以:建议b的默认值为None
42、如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
astring = “1,2,3”
list(astring.split(','))
43、如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
map(int, [‘1’,’2’,’3’])
44、比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?
自己说:能力有限,但可以看出,a, b相同,a, b都是list,所包含的元素都为int, 最后边的b包含的元素是tuple
45、如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?
[x*x for x in range(1, 11)]
46、一行代码实现删除列表中重复的值 ?
alist = [6,9,3,6,5,4,78,5,4,4,4]
list(set(alsit))
47、如何在函数中设置一个全局变量 ?
global var
48、logging模块的作用?以及应用场景?
Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。
这个模块提供不同的日志级别,并可以采用不同的方式记录日志,
比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。
日志是一种可以追踪某些软件运行时所发生事件的方法。软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。
一个事件可以用一个可包含可选变量数据的消息来描述。此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)。
1.日志的作用
通过log的分析,可以方便用户了解系统或软件、应用的运行情况;如果你的应用log足够丰富,
也可以分析以往用户的操作行为、类型喜好、地域分布或其他更多信息;如果一个应用的log同时也分了多个级别,
那么可以很轻易地分析得到该应用的健康状况,及时发现问题并快速定位、解决问题,补救损失。
简单来讲就是,我们通过记录和分析日志可以了解一个系统或软件程序运行情况是否正常,
也可以在应用程序出现故障时快速定位问题。比如,做运维的同学,在接收到报警或各种问题反馈后,
进行问题排查时通常都会先去看各种日志,大部分问题都可以在日志中找到答案。再比如,做开发的同学,
可以通过IDE控制台上输出的各种日志进行程序调试。对于运维老司机或者有经验的开发人员,
可以快速的通过日志定位到问题的根源。可见,日志的重要性不可小觑。日志的作用可以简单总结为以下3点:
程序调试
了解软件程序运行情况,是否正常
软件程序运行故障分析与问题定位
如果应用的日志信息足够详细和丰富,还可以用来做用户行为分析,
如:分析用户的操作行为、类型洗好、地域分布以及其它更多的信息,
由此可以实现改进业务、提高商业利益。
49、请用代码解答实现stack 。
Python: 3.x
class stack(object):
def __init__(self):
self.items = []
def isEmpty(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[-1]
def size(self):
return len(self.items)
50、常用字符串格式化哪几种?
1.最方便的
print 'hello %s and %s' % ('df', 'another df')
但是,有时候,我们有很多的参数要进行格式化,这个时候,一个一个一一对应就有点麻烦了,于是就有了第二种,字典形式的。上面那种是tuple形式的。
2.最好用的
print 'hello %(first)s and %(second)s' % {'first': 'df', 'second': 'another df'}
这种字典形式的字符串格式化方法,有一个最大的好处就是,字典这个东西可以和json文件相互转换,所以,当配置文件使用字符串设置的时候,就显得相当方便。
3.最先进的
print 'hello {first} and {second}'.format(first='df', second='another df')
51、简述 生成器、迭代器、可迭代对象 以及应用场景?
一:语法糖
从字面上看应该是一种语法。“糖”,可以理解为简单、简洁。其实我们也已经意识到,
没有这些被称为“语法糖”的语法,我们也能实现相应的功能,而 “语法糖”使我们可以更加简洁、快速的实现这些功能。
只是Python解释器会把这些特定格式的语法翻译成原本那样复杂的代码逻辑而已,没有什么太高深的东西。
像列表推导式,字典推导式,元组生成器,以及生成器,迭代器应该都是语法糖。
二:生成器(generator)
生成器是构造迭代器的最简单有力的工具,与普通函数不同的只有在返回一个值的时候使用yield来替代return,
然后yield会自动构建好next()和iter()。
三:迭代器(iterator)
迭代器是通过next()来实现的,每调用一次他就会返回下一个元素,当没有下一个元素的时候返回一个StopIteration异常,
所以实际上定义了这个方法的都算是迭代器。
四:可迭代对象(iterable)
Python中经常使用for来对某个对象进行遍历,此时被遍历的这个对象就是可迭代对象,
像常见的list,tuple都是。如果给一个准确的定义的话,就是只要它定义了可以返回一个迭代器的__iter__方法,
或者定义了可以支持下标索引的__getitem__方法(这些双下划线方法会在其他章节中全面解释),
那么它就是一个可迭代对象。
值得一提的是,这就是Python中的多态,而且Python非常推崇鸭子类型。
52、用Python实现一个二分查找的函数。
def binary_search(alist, key)
low, high = 0, 0
mid = len(alist) - 1
time = 0
while low < high:
time += 1
mid = (low + high) // 2
if alist[mid] < key:
low = mid + 1
elif alist[mid] > key:
high = mid - 1
else:
print("Search {} times!\n".format(time))
return mid
print("No Search {} times!\n".format(time))
return False
53.谈谈你对闭包的理解?
闭包 = 代码块 + 执行环境
函数声明的时候,会生成一个独立的作用域
同一作用域的对象可以互相访问
作用域呈层级包含状态,形成作用域链,子作用域的对象可以访问父作用域的对象,反之不能;另外子作用域会使用最近的父作用域的对象
闭包需要满足的条件:
1. 必须有一个内嵌函数
2. 内嵌函数必须引用外部函数中的变量
3. 外部函数的返回值必须是内嵌函数
闭包的概念不太好理解,自己也似懂非懂。请参考下面的阅读。
参考阅读:闭包_百度百科
Python 中的闭包 - Python - 伯乐在线
谈谈自己的理解:python中闭包,闭包的实质 - 稀里糊涂林老冷 - 博客园
54.os和sys模块的作用?
os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
# os模块常用方法
os.remove(‘path/filename’) 删除文件
os.rename(oldname, newname) 重命名文件
os.walk() 生成目录树下的所有文件名
os.chdir('dirname') 改变目录
os.mkdir/makedirs('dirname')创建目录/多层目录
os.rmdir/removedirs('dirname') 删除目录/多层目录
os.listdir('dirname') 列出指定目录的文件
os.getcwd() 取得当前工作目录
os.chmod() 改变目录权限
os.path.basename(‘path/filename’) 去掉目录路径,返回文件名
os.path.dirname(‘path/filename’) 去掉文件名,返回目录路径
os.path.join(path1[,path2[,...]]) 将分离的各部分组合成一个路径名
os.path.split('path') 返回( dirname(), basename())元组
os.path.splitext() 返回 (filename, extension) 元组
os.path.getatime\ctime\mtime 分别返回最近访问、创建、修改时间
os.path.getsize() 返回文件大小
os.path.exists() 是否存在
os.path.isabs() 是否为绝对路径
os.path.isdir() 是否为目录
os.path.isfile() 是否为文件
# sys模块常用方法
sys.argv #命令行参数List,第一个元素是程序本身路径
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.modules.keys() #返回所有已经导入的模块列表
sys.modules #返回系统导入的模块字段,key是模块名,value是模块
sys.exc_info() #获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) #退出程序,正常退出时exit(0)
sys.hexversion #获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version #获取Python解释程序的版本信息
sys.platform #返回操作系统平台名称
sys.maxint # 最大的Int值
sys.stdout #标准输出
sys.stdout.write('aaa') #标准输出内容
sys.stdout.writelines() #无换行输出
sys.stdin #标准输入
sys.stdin.read() #输入一行
sys.stderr #错误输出
sys.exc_clear() #用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix #返回平台独立的python文件安装的位置
sys.byteorder #本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
sys.copyright #记录python版权相关的东西
sys.api_version #解释器的C的API版本
sys.version_info #'final'表示最终,也有'candidate'表示候选,表示版本级别,是否有后继的发行
sys.getdefaultencoding() #返回当前你所用的默认的字符编码格式
sys.getfilesystemencoding() #返回将Unicode文件名转换成系统文件名的编码的名字
sys.builtin_module_names #Python解释器导入的内建模块列表
sys.executable #Python解释程序路径
sys.getwindowsversion() #获取Windows的版本
sys.stdin.readline() #从标准输入读一行,sys.stdout.write(a) 屏幕输出a
sys.setdefaultencoding(name) #用来设置当前默认的字符编码(详细使用参考文档)
sys.displayhook(value) #如果value非空,这个函数会把他输出到sys.stdout(详细使用参考文档)
55、如何生成一个随机数?
Python中使用Random模块来生成随机数
常用的方法有:.randint(), .random(), .randrange(), .sample(), .seed(), .uniform()
56.如何使用python删除一个文件?
os.remove('path/filename') # 删除文件
57、谈谈你对面向对象的理解?
面向对象编程,即OOP,是一种编程范式,满足面向对象编程的语言,
一般会提供类、封装、继承等语法和概念来辅助我们进行面向对象编程。
面向对象是基于万物皆对象这个哲学观点. 所谓的面向对象就是将我们的程序模块化,对象化,
把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面
面向对象的三大特征 继承,封装,多态
一 继承
继承概念:一个类继承另一个类,则称继承的类为子类,被继承的类为父类。
目的:实现代码的复用。
理解:子类与父类的关系并不是日常生活中的父子关系,子类与父类而是一种特殊化与一般化的关系,
是is-a的关系,子类是父类更加详细的分类。如 class dog 继承于 animal,
就可以理解为dog is a animal.注意设计继承的时候.
结果:继承后子类自动拥有了父类的属性和方法,子类可以写自己特有的属性和方法,
目的是实现功能的扩展,子类也可以复写父类的方法即方法的重写。
二 封装
概念:封装也称为信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,
使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,
只保留一些对外接口使之与外部发生联系。
系统的其他部分只有通过包裹在数据外面的被授权的操作来与这个抽象数据类型交流与交互。
也就是说,用户无需知道对象内部方法的实现细节,但可以根据对象提供的外部接口(对象名和参数)访问该对象。
好处:(1)实现了专业的分工。将能实现某一特定功能的代码封装成一个独立的实体后,
各程序员可以在需要的时候调用,从而实现了专业的分工。
(2)隐藏信 息,实现细节。通过控制访问权限可以将可以将不想让客户端程序员看到的信息隐藏起来,
如某客户的银行的密码需要保密,只能对该客户开发权限。
三、多态
概念:相同的事物,调用其相同的方法,参数也相同时,但表现的行为却不同。
理解:子类以父类的身份出现,但做事情时还是以自己的方法实现。
子类以父类的身份出现需要向上转型(upcast),其中向上转型是由JVM自动实现的,
是安全的,但向下转型(downcast)是不安全的,需要强制转换。
子类以父类的身份出现时自己特有的属性和方法将不能使用。
“面向过程”和“面向对象”的区别
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,
使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,
建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
。
可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,面向过程的设计思路就是首先分析问题的步骤:
1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,
8、返回步骤 2,9、输出最后结果。把上面每个步骤用不同的方法来实现。
如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思路来 解决问题。
整个五子棋可以分为
1、黑白双方,这两方的行为是一模一样的,
2、棋盘系统,负责绘制画面,
3、规则系统,负责判定诸如犯规、输赢等。第一类对 象(玩家对象)负责接受用户输入,
并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,
同时利用 第三类对象(规则系统)来对棋局进行判定。
58.Python面向对象中的继承有什么特点?
继承更多了是为了多态,也可提升代码的复用程度。
特点:
在继承中基类的构造(\_\_init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用;
Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找);
59.面向对象深度优先和广度优先是什么?
当出现多重继承并产生菱形交叉时查找属性或方法路径顺序。
参考阅读:你真的理解Python中MRO算法吗?
60.面向对象中super的作用?
super() 函数是用于调用父类(超类)的一个方法。
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx
61.是否使用过functools中的函数?其作用是什么?
@functools.wraps:使用装饰器时保留被装饰函数的签名和docstring
@functools.lru_cache(maxsize=128, typed=False):(下面给出例子)
functools.partial(func, *args, **keywords):
用于静态Web内容的LRU缓存示例:
@lru_cache(maxsize=32)
def get_pep(num):
'Retrieve text of a Python Enhancement Proposal'
resource = 'http://www.python.org/dev/peps/pep-%04d/' % num
try:
with urllib.request.urlopen(resource) as s:
return s.read()
except urllib.error.HTTPError:
return 'Not Found'
>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
... pep = get_pep(n)
... print(n, len(pep))
>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
使用缓存实现动态编程技术高效计算斐波那契数列的示例:
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
partial()用于冻结函数的某些参数和/或关键字参数,生成一个简化的签名对象。例如,用于创建一个类似int()函数的可调用对象,其中base参数默认为2:
>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
62.列举面向对象中带爽下划线的特殊方法,如:
__new__、__init__
__setattr__:添加/修改属性会触发它的执行
__delattr__:删除属性的时候会触发
__getattr__:只有在使用点调用属性且属性不存在的时候才会触发
__getattribute__:当__getattribute__与__getattr__同时存在,无论属性是否存在,只会执行__getattrbute__,除非__getattribute__在执行过程中抛出异常AttributeError
__get__: 调用一个属性时触发
__set__: 为一个属性赋值时触发
__delete__: 采用del删除一个属性时触发
__setitem__,__getitem__和__delitem__
这三个方法为实例提供了类字典操作
__next__和__iter__实现迭代器协议
__enter__和__exit__实现上下文管理协议
63、如何判断是函数还是方法?
通过type()可以知道对象所属的类型,函数是<class 'function'>,方法是<class 'method'>
64、静态方法和类方法区别?
实例方法只能被实例对象调用,静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。
实例方法,第一个参数必须要默认传实例对象,一般习惯用self。
静态方法,参数没有要求。
类方法,第一个参数必须要默认传类,一般习惯用cls。
65、列举面向对象中的特殊成员以及应用场景?
1.__doc__ :打印类的描述信息
2.__module__:表示当前操作的对象在那个模块
3.__class__:表示当前操作的对象的类是什么
4. __init__ :构造方法,通过类创建对象时,自动触发执行
5.__del__:析构方法,当对象在内存中被释放时,自动触发执行
6.__call__:对象后面加括号,触发执行
7.__dict__:查看类或对象中的所有成员
8.__str__:如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值
9.__getitem__、__setitem__、__delitem__:
注:用于索引操作,如字典。以上分别表示获取、设置、删除数据
10.__new__\__metaclass__ *(自定义类)
__new__:是用来创建实例的,对类实例化之前进行定制,可以用到。
__metaclass__:定义一个类如何被创建
1、2、3、4、5 能组成多少个互不相同且无重复的三位数
l = [1, 2, 3, 4, 5]
cnt = 0
for i in range(5):
for j in range(5):
if j == i:
continue
for k in range(5):
if k != j and k != i:
print(l[i]*100+l[j]*10+l[k])
cnt += 1
print(cnt) # 60
67、什么是反射?以及应用场景?
解释一: python的反射,它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动。
解释二: 需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,
这是我们需要用一个特殊的方法或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射。
几个重要方法:
hasattr: 判断对象中是否有这个方法或变量
getattr: 获取对象中的方法或变量的内存地址
setattr: 为对象添加变量或方法
delattr: 删除对象中的变量。注意:不能用于删除方法
68.metaclass作用?以及应用场景?
元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为
元类的实例化的结果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例),type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象
场景:当然是定制类的行为了….
参考阅读:使用元类 - 廖雪峰的官方网站
69.用尽量多的方法实现单例模式。
# 1. 使用模块:Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件;
# 当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码
#foo1.py
class Singleton:
def foo(self):
pass
singleton = Singleton()
#foo.py
from foo1 import singleton
# 2. 静态变量方法(自定义new方法)
class Singleton(object):
def __new__(cls,a):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls)
return cls._instance
def __init__(self,a):
self.a = a
def aa(self):
print(self.a)
a = Singleton("a")
# 3. 使用装饰器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
@Singleton
class A:
pass
# 4. 使用类方法获取单例(考虑多线程)
# 这种方式实现的单例模式,使用时会有限制,以后实例化必须通过 obj = Singleton.instance()
# 如果用 obj=Singleton() ,这种方式得到的不是单例
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
obj = Singleton.instance()
# 5. 基于metaclass方式实现
"""
类由type创建,创建类时,type的__init__方法自动执行,
类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)
"""
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().__call__(*args, **kwargs)
return cls._instance
class Foo(metaclass=SingletonType):
def __init__(self, name):
self.name = name
obj1 = Foo('name')
obj2 = Foo('name')
print(obj1 is obj2)
70、装饰器的写法以及应用场景。
# 1. 授权
# 2. 日志
# 3. 带参数的装饰器
from functools import wraps
def logit(logfile='out.log'):
def logging_decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打开logfile,并写入内容
with open(logfile, 'a') as opened_file:
# 现在将日志打到指定的logfile
opened_file.write(log_string + '\n')
return func(*args, **kwargs)
return wrapped_function
return logging_decorator
@logit()
def myfunc1():
pass
@logit(logfile='func2.log')
def myfunc2():
pass
# 4. 装饰类 的装饰器:类实例化的过程,也是函数调用
from functools import wraps
def foo(bar):
@wraps(bar)
def __foo(*args,**kwargs):
print('before')
obj = bar(*args, **kwargs)
print('after')
return obj
return __foo
@foo
class Person:
def __init__(self, name):
self.name = name
# 5. 类装饰器:重写__call__()方法
# Q: 这里如果被装饰的函数有参数,应该怎么写呢?
class foo:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('begin...')
self.func(*args, **kwargs)
print('end')
@foo # bar = foo(bar)
def bar():
print('in bar')
71、异常处理写法以及如何主动跑出异常(应用场景)
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
finally:
<语句> #语句无论是否发生异常都将执行最后的代码。
raise语句自动触发异常
raise语法格式如下:
raise [Exception [, args [, traceback]]]
语句中 Exception 是异常的类型(例如,NameError)参数标准异常中任一种,args 是自已提供的异常参数。
最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
72.什么是面向对象的mro
对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
- 子类会先于父类被检查
- 多个父类会根据它们在列表中的顺序被检查
- 如果对下一个类存在两个合法的选择,选择第一个父类
73、isinstance作用以及应用场景?
描述:
isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
语法:
以下是 isinstance() 方法的语法:
isinstance(object, classinfo)
参数:
object -- 实例对象。
classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。
返回值
如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。。
74、写代码并实现:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
class Solution():
def twoSum(self, nums, targets):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
dct = {}
for index, value in enumerate(nums):
j = target - value
if j in dct:
return [ dct[j], index]
else:
dct[value] = index
- json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
支持的数据类型:
对于,特殊的数据类型,例如,datatime() 时间类型,json.dumps不支持该数据类型的序列化;那么就可以通过自定义处理来扩展,使用的时候,只要在json.dumps()方法中增加一个cls参数即可:
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime(‘%Y-%m-%d %H:%M:%S‘)
elif isinstance(obj, date):
return obj.strftime(‘%Y-%m-%d‘)
else:
return json.JSONEncoder.default(self, obj)
# ds = json.dumps(d, cls=JsonCustomEncoder)
- json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
import json
a=json.dumps({"ddf":"你好"},ensure_ascii=False)
print(a) #{"ddf": "你好"}
77.什么是断言?应用场景?
Python的assert是用来检查一个条件,如果它为真,就不做任何事。如果它为假,则会抛出AssertError并且包含错误信息。
x = 23
assert x > 0, "x is not zero or negative"
assert x%2 == 0, "x is not an even number"
断言应该用于:
☆防御型的编程
☆运行时检查程序逻辑
☆检查约定
☆程序常量
☆检查文档
一个好的使用断言的方式是检查程序的不变量。一个不变量是一些你需要依赖它为真的情况,除非一个bug导致它为假。如果有bug,最好能够尽早发现,所以我们为它进行一个测试,但是又不想减慢代码运行速度。所以就用断言,因为它能在开发时打开,在产品阶段关闭。
78.有用过with statement吗?它的好处是什么?
with语句会在嵌套的代码执行之后,自动关闭文件。这种做法的还有另一个优势就是,无论嵌套的代码是以何种方式结束的,它都关闭文件。如果在嵌套的代码中发生异常,它能够在外部exception handler catch异常前关闭文件。如果嵌套代码有return/continue/break语句,它同样能够关闭文件。
from contextlib import contextmanager
import os
@contextmanager
def working_directory(path):
current_dir = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(current_dir)
with working_directory("../"):
# do something within ../
print('in', os.getcwd())
# here I am back again in the original working directory
print('out', os.getcwd())
79.使用代码实现查看列举目录下的所有文件。
import os
ret = []
for root, dirs, files in os.walk(os.getcwd(), topdown=True):
# print([os.path.join(root, file) for file in files])
ret.extend([os.path.join(root, file) for file in files])
print(ret)
- 简述 yield和yield from关键字。
当一个函数中存在yield关键字时,它就变成了一个生成器,每次迭代求值一次,节省内存;
yield from 意思是从一个可迭代对象中逐一取值并yield:
yield from iterable
# 与上面等价
for item in iterable:
yield item