python这个代码有什么装箱问题 python代码?

这段python代码有啥问题(萌新求指导)。。_百度知道
这段python代码有啥问题(萌新求指导)。。
我有更好的答案
ai_settings=Settings()是不是应该改成ai_settings=settings()
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。Python 错误和异常小结
转载 &发布时间:日 21:04:38 & 作者:
这不是一篇关于Python异常的全面介绍的文章,这只是在学习Python异常后的一篇笔记式的记录和小结性质的文章
事先说明哦,这不是一篇关于Python异常的全面介绍的文章,这只是在学习Python异常后的一篇笔记式的记录和小结性质的文章。什么?你还不知道什么是异常,额... 1.Python异常类 Python是面向对象语言,所以程序抛出的异常也是类。常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不用Python了)。
尝试访问一个没有申明的变量
ZeroDivisionError
SyntaxError
IndexError
索引超出序列范围
请求一个不存在的字典关键字
输入输出错误(比如你要读的文件不存在)
AttributeError
尝试访问未知的对象属性
ValueError
传给函数的参数类型不正确,比如给int()函数传入字符串形
2.捕获异常
&&& Python完整的捕获异常的语句有点像:
代码如下:try:&&& try_suiteexcept Exception1,Exception2,...,Argument:&&& exception_suite......&& #other exception blockelse:&&& no_exceptions_detected_suitefinally:&&& always_execute_suite
额...是不是很复杂?当然,当我们要捕获异常的时候,并不是必须要按照上面那种格式完全写下来,我们可以丢掉else语句,或者finally语句;甚至不要exception语句,而保留finally语句。额,晕了?好吧,下面,我们就来一一说明啦。
2.1.try...except...语句
&&& try_suite不消我说大家也知道,是我们需要进行捕获异常的代码。而except语句是关键,我们try捕获了代码段try_suite里的异常后,将交给except来处理。
&&& try...except语句最简单的形式如下:
代码如下:try:&&& try_suiteexcept:&&& exception block
上面except子句不跟任何异常和异常参数,所以无论try捕获了任何异常,都将交给except子句的exception block来处理。如果我们要处理特定的异常,比如说,我们只想处理除零异常,如果其他异常出现,就让其抛出不做处理,该怎么办呢?这个时候,我们就要给except子句传入异常参数啦!那个ExceptionN就是我们要给except子句的异常类(请参考异常类那个表格),表示如果捕获到这类异常,就交给这个except子句来处理。比如:
代码如下:try:&&& try_suiteexcept Exception:&&& exception block
举个例子:
代码如下:&&& try:...&&&& res = 2/0... except ZeroDivisionError:...&&&& print "Error:Divisor must not be zero!"... Error:Divisor must not be zero!
看,我们真的捕获到了ZeroDivisionError异常!那如果我想捕获并处理多个异常怎么办呢?有两种办法,一种是给一个except子句传入多个异常类参数,另外一种是写多个except子句,每个子句都传入你想要处理的异常类参数。甚至,这两种用法可以混搭呢!下面我就来举个例子。
代码如下:try:&&& floatnum = float(raw_input("Please input a float:"))&&& intnum = int(floatnum)&&& print 100/intnumexcept ZeroDivisionError:&&& print "Error:you must input a float num which is large or equal then 1!"except ValueError:&&& print "Error:you must input a float num!"
[root@Cherish tmp]# python test.py Please input a float:fjiaError:you must input a float num![root@Cherish tmp]# python test.py Please input a float:0.9999Error:you must input a float num which is large or equal then 1![root@Cherish tmp]# python test.py Please input a float:25.0914
上面的例子大家一看都懂,就不再解释了。只要大家明白,我们的except可以处理一种异常,多种异常,甚至所有异常就可以了。
&&& 大家可能注意到了,我们还没解释except子句后面那个Argument是什么东西?别着急,听我一一道来。这个Argument其实是一个异常类的实例(别告诉我你不知到什么是实例),包含了来自异常代码的诊断信息。也就是说,如果你捕获了一个异常,你就可以通过这个异常类的实例来获取更多的关于这个异常的信息。例如:
代码如下:&&& try:...&&&& 1/0... except ZeroDivisionError,reason:...&&&& pass... &&& type(reason)&type 'exceptions.ZeroDivisionError'&&&& print reasoninteger division or modulo by zero&&& reasonZeroDivisionError('integer division or modulo by zero',)&&& reason.__class__&type 'exceptions.ZeroDivisionError'&&&& reason.__class__.__doc__'Second argument to a division or modulo operation was zero.'&&& reason.__class__.__name__'ZeroDivisionError'
上面这个例子,我们捕获了除零异常,但是什么都没做。那个reason就是异常类ZeroDivisionError的实例,通过type就可以看出。
2.2try ... except...else语句&&& 现在我们来说说这个else语句。Python中有很多特殊的else用法,比如用于条件和循环。放到try语句中,其作用其实也差不多:就是当没有检测到异常的时候,则执行else语句。举个例子大家可能更明白些:
代码如下:&&& import syslog&&& try:...&&&& f = open("/root/test.py")... except IOError,e:...&&&& syslog.syslog(syslog.LOG_ERR,"%s"%e)... else:...&&&& syslog.syslog(syslog.LOG_INFO,"no exception caught\n")... &&& f.close()
2.3 finally子句&&& finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try...finally,也可以配合except等使用。
例如2.2的例子,如果出现其他异常,无法捕获,程序异常退出,那么文件 f 就没有被正常关闭。这不是我们所希望看到的结果,但是如果我们把f.close语句放到finally语句中,无论是否有异常,都会正常关闭这个文件,岂不是很 妙
代码如下:&&& import syslog&&& try:...&&&& f = open("/root/test.py")... except IOError,e:...&&&& syslog.syslog(syslog.LOG_ERR,"%s"%e)... else:...&&&& syslog.syslog(syslog.LOG_INFO,"no exception caught\n")... finally: &&& & & f.close()
&大家看到了没,我们上面那个例子竟然用到了try,except,else,finally这四个子句!:-),是不是很有趣?到现在,你就基本上已经学会了如何在Python中捕获常规异常并处理之。
3.两个特殊的处理异常的简便方法
3.1断言(assert)&&& 什么是断言,先看语法:
代码如下:assert expression[,reason]
其中assert是断言的关键字。执行该语句的时候,先判断表达式expression,如果表达式为真,则什么都不做;如果表达式不为真,则抛出异常。reason跟我们之前谈到的异常类的实例一样。不懂?没关系,举例子!最实在!
代码如下:&&& assert len('love') == len('like')&&& assert 1==1&&& assert 1==2,"1 is not equal 2!"Traceback (most recent call last):& File "&stdin&", line 1, in &module&AssertionError: 1 is not equal 2!
我们可以看到,如果assert后面的表达式为真,则什么都不做,如果不为真,就会抛出AssertionErro异常,而且我们传进去的字符串会作为异常类的实例的具体信息存在。其实,assert异常也可以被try块捕获:
代码如下:&&& try:...&&&& assert 1 == 2 , "1 is not equal 2!"... except AssertionError,reason:...&&&& print "%s:%s"%(reason.__class__.__name__,reason)... AssertionError:1 is not equal 2!&&& type(reason)&type 'exceptions.AssertionError'&
3.2.上下文管理(with语句)&& 如果你使用try,except,finally代码仅仅是为了保证共享资源(如文件,数据)的唯一分配,并在任务结束后释放它,那么你就有福了!这个with语句可以让你从try,except,finally中解放出来!语法如下:
代码如下:with context_expr [as var]:&&& with_suite
是不是不明白?很正常,举个例子来!
代码如下:&&& with open('/root/test.py') as f:...&&&& for line in f:...&&&&&&&& print line
上面这几行代码干了什么?&&& (1)打开文件/root/test.py&&& (2)将文件对象赋值给& f&&& (3)将文件所有行输出&&&& (4)无论代码中是否出现异常,Python都会为我们关闭这个文件,我们不需要关心这些细节。&&& 这下,是不是明白了,使用with语句来使用这些共享资源,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表:file
decimal.Contextthread.LockTypethreading.Lockthreading.RLockthreading.Conditionthreading.Semaphorethreading.BoundedSemaphore
&&& 至于什么是上下文管理协议,如果你不只关心怎么用with,以及哪些对象可以使用with,那么我们就不比太关心这个问题:)
4.抛出异常(raise)
&&& 如果我们想要在自己编写的程序中主动抛出异常,该怎么办呢?raise语句可以帮助我们达到目的。其基本语法如下:
代码如下:raise [SomeException [, args [,traceback]]
第一个参数,SomeException必须是一个异常类,或异常类的实例 &&& 第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。&&& 第三个参数traceback很少用,主要是用来提供一个跟中记录对象(traceback)&&& 下面我们就来举几个例子。
代码如下:&&& raise NameErrorTraceback (most recent call last):& File "&stdin&", line 1, in &module&NameError&&& raise NameError()& #异常类的实例Traceback (most recent call last):& File "&stdin&", line 1, in &module&NameError&&& raise NameError,("There is a name error","in test.py")Traceback (most recent call last):& File "&stdin&", line 1, in &module&&&& raise NameError("There is a name error","in test.py")& #注意跟上面一个例子的区别Traceback (most recent call last):& File "&stdin&", line 1, in &module&NameError: ('There is a name error', 'in test.py')&&& raise NameError,NameError("There is a name error","in test.py")& #注意跟上面一个例子的区别Traceback (most recent call last):& File "&stdin&", line 1, in &module&NameError: ('There is a name error', 'in test.py')
其实,我们最常用的还是,只传入第一个参数用来指出异常类型,最多再传入一个元组,用来给出说明信息。如上面第三个例子。
5.异常和sys模块
&&& 另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟中记录对象)
代码如下:&&& try:...&&&& 1/0... except:...&&&& import sys...&&&& tuple = sys.exc_info()... &&& print tuple(&type 'exceptions.ZeroDivisionError'&, ZeroDivisionError('integer division or modulo by zero',), &traceback object at 0x7f538a318b48&)&&& for i in tuple:...&&&& print i... &type 'exceptions.ZeroDivisionError'& #异常类 & &integer division or modulo by zero #异常类的实例&traceback object at 0x7f538a318b48& #跟踪记录对象
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Python 面试题很全的 Python 面试题 ·
· · 分享到:65原文出处:
Python语言特性1 Python的函数参数传递看两个例子:Python12345a = 1def fun(a):
a = 2fun(a)print a
# 1Python12345a = []def fun(a):
a.append(1)fun(a)print a
# [1]所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。这里记住的是类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。(这就是这个问题的重点)当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了.所以第一个例子里函数把引用指向了一个不可变对象,当函数返回的时候,外面的引用没半毛感觉.而第二个例子就不一样了,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改.如果还不明白的话,这里有更好的解释: 2 Python中的元类(metaclass)这个非常的不常用,但是像ORM这种复杂的结构还是会需要的,详情请看:《》3 @staticmethod和@classmethodPython其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下:Python12345678910111213141516def foo(x):
print "executing foo(%s)"%(x)class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print "executing class_foo(%s,%s)"%(cls,x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)"%xa=A()这里先理解下函数参数里面的self和cls.这个self和cls是对类或者实例的绑定,对于一般的函数来说我们可以这么调用foo(x),这个函数就是最常用的,它的工作跟任何东西(类,实例)无关.对于实例方法,我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self, x),为什么要这么做呢?因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的a.foo(x)(其实是foo(a, x)).类方法一样,只不过它传递的是类而不是实例,A.class_foo(x).注意这里的self和cls可以替换别的参数,但是python的约定是这俩,还是不要改的好.对于静态方法其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.\实例方法类方法静态方法a = A()a.foo(x)a.class_foo(x)a.static_foo(x)A不可用A.class_foo(x)A.static_foo(x)更多关于这个问题:4 类变量和实例变量Python123456789class Person:
name="aaa"p1=Person()p2=Person()p1.name="bbb"print p1.name
# bbbprint p2.name
# aaaprint Person.name
# aaa类变量就是供类使用的变量,实例变量就是供实例使用的.这里p1.name="bbb"是实例调用了类变量,这其实和上面第一个问题一样,就是函数传参的问题,p1.name一开始是指向的类变量name="aaa",但是在实例的作用域里把类变量的引用改变了,就变成了一个实例变量,self.name不再引用Person的类变量name了.可以看看下面的例子:Python123456789class Person:
name=[]p1=Person()p2=Person()p1.name.append(1)print p1.name
# [1]print p2.name
# [1]print Person.name
# [1]参考:5 Python自省这个也是python彪悍的特性.自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance().6 字典推导式可能你见过列表推导时,却没有见过字典推导式,在2.7中才加入的:Python1d = {key: value for (key, value) in iterable}7 Python中单下划线和双下划线Python1234567891011121314&&& class MyClass():...
def __init__(self):...
self.__superprivate = "Hello"...
self._semiprivate = ", world!"...&&& mc = MyClass()&&& print mc.__superprivateTraceback (most recent call last):
File "&stdin&", line 1, in &module&AttributeError: myClass instance has no attribute '__superprivate'&&& print mc._semiprivate, world!&&& print mc.__dict__{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}__foo__:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突._foo:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.__foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名.详情见:或者: 8 字符串格式化:%和.format.format在许多方面看起来更便利.对于%最烦人的是它无法同时传递一个变量和元组.你可能会想下面的代码不会有什么问题:Python1"hi there %s" % name但是,如果name恰好是(1,2,3),它将会抛出一个TypeError异常.为了保证它总是正确的,你必须这样做:Python1"hi there %s" % (name,)
# 提供一个单元素的数组而不是一个参数但是有点丑..format就没有这些问题.你给的第二个问题也是这样,.format好看多了.你为什么不用它?不知道它(在读这个之前)为了和Python2.5兼容(譬如logging库建议使用%())9 迭代器和生成器这个是stackoverflow里python排名第一的问题,值得一看: 这是中文版: 10 *args and **kwargs用*args和**kwargs只是为了方便并没有强制使用它们.当你不确定你的函数里将要传递多少参数时你可以用*args.例如,它可以传递任意数量的参数:Python12345678&&& def print_everything(*args):
for count, thing in enumerate(args):...
print '{0}. {1}'.format(count, thing)...&&& print_everything('apple', 'banana', 'cabbage')0. apple1. banana2. cabbage相似的,**kwargs允许你使用没有事先定义的参数名:Python1234567&&& def table_things(**kwargs):...
for name, value in kwargs.items():...
print '{0} = {1}'.format(name, value)...&&& table_things(apple = 'fruit', cabbage = 'vegetable')cabbage = vegetableapple = fruit你也可以混着用.命名参数首先获得参数值然后所有的其他参数都传递给*args和**kwargs.命名参数在列表的最前端.例如:Python1def table_things(titlestring, **kwargs)*args和**kwargs可以同时在函数的定义中,但是*args必须在**kwargs前面.当调用函数时你也可以用*和**语法.例如:Python1234567&&& def print_three_things(a, b, c):...
print 'a = {0}, b = {1}, c = {2}'.format(a,b,c)...&&& mylist = ['aardvark', 'baboon', 'cat']&&& print_three_things(*mylist)a = aardvark, b = baboon, c = cat就像你看到的一样,它可以传递列表(或者元组)的每一项并把它们解包.注意必须与它们在函数里的参数相吻合.当然,你也可以在函数定义或者函数调用时用*.11 面向切面编程AOP和装饰器这个AOP一听起来有点懵,同学面阿里的时候就被问懵了…装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。这个问题比较大,推荐: 中文: 12 鸭子类型“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。比如在python中,有很多file-like的东西,比如StringIO,GzipFile,socket。它们有很多相同的方法,我们把它们当作文件使用。又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式。13 Python中重载引自知乎:函数重载主要是为了解决两个问题。可变参数类型。可变参数个数。另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函数的功能其实不同,那么不应当使用重载,而应当使用一个名字不同的函数。好吧,那么对于情况 1 ,函数功能相同,但是参数类型不同,python 如何处理?答案是根本不需要处理,因为 python 可以接受任何类型的参数,如果函数的功能相同,那么不同的参数类型在 python 中很可能是相同的代码,没有必要做成两个不同函数。那么对于情况 2 ,函数功能相同,但参数个数不同,python 如何处理?大家知道,答案就是缺省参数。对那些缺少的参数设定为缺省参数即可解决问题。因为你假设函数功能相同,那么那些缺少的参数终归是需要用的。好了,鉴于情况 1 跟 情况 2 都有了解决方案,python 自然就不需要函数重载了。14 新式类和旧式类这个面试官问了,我说了老半天,不知道他问的真正意图是什么.这篇文章很好的介绍了新式类的特性: 新式类很早在2.2就出现了,所以旧式类完全是兼容的问题,Python3里的类全部都是新式类.这里有一个MRO问题可以了解下(新式类是广度优先,旧式类是深度优先),&Python核心编程&里讲的也很多.15 __new__和__init__的区别这个__new__确实很少见到,先做了解吧.__new__是一个静态方法,而__init__是一个实例方法.__new__方法会返回一个创建的实例,而__init__什么都不返回.只有在__new__返回一个cls的实例时后面的__init__才能被调用.当创建一个新实例时调用__new__,初始化一个实例时用__init__.ps: __metaclass__是创建类时起作用.所以我们可以分别使用__metaclass__,__new__和__init__来分别在类创建,实例创建和实例初始化的时候做一些小手脚.16 单例模式这个绝对常考啊.绝对要记住1~2个方法,当时面试官是让手写的.1 使用__new__方法Python123456789class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instanceclass MyClass(Singleton):
a = 12 共享属性创建实例时把所有实例的__dict__指向同一个字典,这样它们具有相同的属性和方法.Python123456789class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
ob = super(Borg, cls).__new__(cls, *args, **kw)
ob.__dict__ = cls._state
return obclass MyClass2(Borg):
a = 13 装饰器版本Python1234567891011def singleton(cls, *args, **kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance@singletonclass MyClass:
...4 import方法作为python的模块是天然的单例模式Python1234567891011# mysingleton.pyclass My_Singleton(object):
def foo(self):
passmy_singleton = My_Singleton()# to usefrom mysingleton import my_singletonmy_singleton.foo()17 Python中的作用域Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的。当 Python 遇到一个变量的话他会按照这样的顺序进行搜索:本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)18 GIL线程全局锁线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.见解决办法就是多进程和下面的协程(协程也只是单CPU,但是能减小切换代价提升性能).19 协程知乎被问到了,呵呵哒,跪了简单点说协程是进程和线程的升级版,进程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态.Python里最常见的yield就是协程的思想!可以查看第九个问题.20 闭包闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。当一个内嵌函数引用其外部作作用域的变量,我们就会得到一个闭包. 总结一下,创建一个闭包必须满足以下几点:必须有一个内嵌函数内嵌函数必须引用外部函数中的变量外部函数的返回值必须是内嵌函数感觉闭包还是有难度的,几句话是说不明白的,还是查查相关资料.重点是函数运行后并不会被撤销,就像16题的instance字典一样,当函数运行完后,instance并不被销毁,而是继续留在内存空间里.这个功能类似类里的类变量,只不过迁移到了函数上.闭包就像个空心球一样,你知道外面和里面,但你不知道中间是什么样.21 lambda函数其实就是一个匿名函数,为什么叫lambda?因为和后面的函数式编程有关.推荐: 22 Python函数式编程这个需要适当的了解一下吧,毕竟函数式编程在Python中也做了引用.推荐: python中函数式编程支持:filter 函数的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个seq中的元素;返回一个使bool_seq返回值为true的元素的序列。Python1234&&&a = [1,2,3,4,5,6,7]&&&b = filter(lambda x: x & 5, a)&&&print b&&&[6,7]map函数是对一个序列的每个项依次执行函数,下面是对一个序列每个项都乘以2:Python123&&& a = map(lambda x:x*2,[1,2,3])&&& list(a)[2, 4, 6]reduce函数是对一个序列的每个项迭代调用函数,下面是求3的阶乘:Python12&&& reduce(lambda x,y:x*y,range(1,4))623 Python里的拷贝引用和copy(),deepcopy()的区别Python1234567891011121314151617181920import copya = [1, 2, 3, 4, ['a', 'b']]
#原始对象b = a
#赋值,传对象的引用c = copy.copy(a)
#对象拷贝,浅拷贝d = copy.deepcopy(a)
#对象拷贝,深拷贝a.append(5)
#修改对象aa[4].append('c')
#修改对象a中的['a', 'b']数组对象print 'a = ', aprint 'b = ', bprint 'c = ', cprint 'd = ', d输出结果:a =
[1, 2, 3, 4, ['a', 'b', 'c'], 5]b =
[1, 2, 3, 4, ['a', 'b', 'c'], 5]c =
[1, 2, 3, 4, ['a', 'b', 'c']]d =
[1, 2, 3, 4, ['a', 'b']]24 Python垃圾回收机制Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。1 引用计数PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。优点:简单实时性缺点:维护引用计数消耗资源循环引用2 标记-清除机制基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。3 分代技术分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。Python默认定义了三代对象集合,索引数越大,对象存活时间越长。举例:当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。25 Python的List推荐: 26 Python的isis是对比地址,==是对比值27 read,readline和readlinesread 读取整个文件readline 读取下一行,使用生成器方法readlines 读取整个文件到一个迭代器以供我们遍历28 Python2和3的区别推荐:《》操作系统1 select,poll和epoll其实所有的I/O都是轮询的方法,只不过实现的层面不同罢了.这个问题可能有点深入了,但相信能回答出这个问题是对I/O多路复用有很好的了解了.其中tornado使用的就是epoll的.基本上select有3个缺点:连接数受限查找配对速度慢数据由内核拷贝到用户态poll改善了第一个缺点epoll改了三个缺点.关于epoll的: 2 调度算法先来先服务(FCFS, First Come First Serve)短作业优先(SJF, Shortest Job First)最高优先权调度(Priority Scheduling)时间片轮转(RR, Round Robin)多级反馈队列调度(multilevel feedback queue scheduling)实时调度算法:最早截至时间优先 EDF最低松弛度优先 LLF3 死锁原因:竞争资源程序推进顺序不当必要条件:互斥条件请求和保持条件不剥夺条件环路等待条件处理死锁基本方法:预防死锁(摒弃除1以外的条件)避免死锁(银行家算法)检测死锁(资源分配图)解除死锁剥夺资源撤销进程4 程序编译与链接推荐: Bulid过程可以分解为4个步骤:预处理(Prepressing), 编译(Compilation)、汇编(Assembly)、链接(Linking)以c语言为例:1 预处理预编译过程主要处理那些源文件中的以“#”开始的预编译指令,主要处理规则有:将所有的“#define”删除,并展开所用的宏定义处理所有条件预编译指令,比如“#if”、“#ifdef”、 “#elif”、“#endif”处理“#include”预编译指令,将被包含的文件插入到该编译指令的位置,注:此过程是递归进行的删除所有注释添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或警告时可显示行号保留所有的#pragma编译器指令。2 编译编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。这个过程是整个程序构建的核心部分。3 汇编汇编器是将汇编代码转化成机器可以执行的指令,每一条汇编语句几乎都是一条机器指令。经过编译、链接、汇编输出的文件成为目标文件(Object File)4 链接链接的主要内容就是把各个模块之间相互引用的部分处理好,使各个模块可以正确的拼接。链接的主要过程包块 地址和空间的分配(Address and Storage Allocation)、符号决议(Symbol Resolution)和重定位(Relocation)等步骤。5 静态链接和动态链接静态链接方法:静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来静态库的链接可以使用静态链接,动态链接库也可以使用这种方法链接导入库动态链接方法:使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态链接的程序6 虚拟内存技术虚拟存储器是值具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储系统.7 分页和分段分页: 用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。分段: 将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。分页与分段的主要区别页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要.段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要.页的大小固定,由系统确定,将逻辑地址划分为页号和页内地址是由机器硬件实现的.而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时根据信息的性质来划分.分页的作业地址空间是一维的.分段的地址空间是二维的.8 页面置换算法最佳置换算法OPT:不可能实现先进先出FIFO最近最久未使用算法LRU:最近一段时间里最久没有使用过的页面予以置换.clock算法9 边沿触发和水平触发边缘触发是指每当状态变化时发生一个 io 事件,条件触发是只要满足条件就发生一个 io 事件数据库1 事务数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。2 数据库索引推荐: 聚集索引,非聚集索引,B-Tree,B+Tree,最左前缀原理3 Redis原理4 乐观锁和悲观锁悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。5 MVCC6 MyISAM和InnoDBMyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。网络1 三次握手客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数 A。服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。2 四次挥手3 ARP协议地址解析协议(Address Resolution Protocol): 根据IP地址获取物理地址的一个TCP/IP协议4 urllib和urllib2的区别这个面试官确实问过,当时答的urllib2可以Post而urllib不可以.urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,你不可以伪装你的User Agent字符串等。5 Post和Getget: post: 6 Cookie和SessionCookieSession储存位置客户端服务器端目的跟踪会话,也可以保存用户偏好设置或者保存用户名密码等跟踪会话安全性不安全安全session技术是要使用到cookie的,之所以出现session技术,主要是为了安全。7 apache和nginx的区别nginx 相对 apache 的优点:轻量级,同样起web 服务,比apache 占用更少的内存及资源抗并发,nginx 处理请求是异步非阻塞的,支持更多的并发连接,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能配置简洁高度模块化的设计,编写模块相对简单社区活跃apache 相对nginx 的优点:rewrite ,比nginx 的rewrite 强大模块超多,基本想到的都可以找到少bug ,nginx 的bug 相对较多超稳定8 网站用户密码保存明文保存明文hash后保存,如md5MD5+Salt方式,这个salt可以随机知乎使用了Bcrypy(好像)加密9 HTTP和HTTPS状态码定义1xx 报告接收到请求,继续进程2xx 成功步骤成功接收,被理解,并被接受3xx 重定向为了完成请求,必须采取进一步措施4xx 客户端出错请求包括错的顺序或不能完成5xx 服务器出错服务器无法完成显然有效的请求403: Forbidden404: Not FoundHTTPS握手,对称加密,非对称加密,TLS/SSL,RSA10 XSRF和XSSCSRF(Cross-site request forgery)跨站请求伪造XSS(Cross Site Scripting)跨站脚本攻击CSRF重点在请求,XSS重点在脚本11 幂等 IdempotenceHTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。(注意是副作用)GET ,不会改变资源的状态,不论调用一次还是N次都没有副作用。请注意,这里强调的是一次和N次具有相同的副作用,而不是每次GET的结果相同。GET 这个HTTP请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足幂等性的。DELETE方法用于删除资源,有副作用,但它应该满足幂等性。比如:DELETE ,调用一次和N次对系统产生的副作用是相同的,即删掉id为4231的帖子;因此,调用者可以多次调用或刷新页面而不必担心引起错误。POST所对应的URI并非创建的资源本身,而是资源的接收者。比如:POST 的语义是在下创建一篇帖子,HTTP响应中应包含帖子的创建状态以及帖子的URI。两次相同的POST请求会在服务器端创建两份资源,它们具有不同的URI;所以,POST方法不具备幂等性。PUT所对应的URI是要创建或更新的资源本身。比如:PUT 的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。12 RESTful架构(SOAP,RPC)推荐: 13 SOAPSOAP(原为Simple Object Access Protocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,使用在计算机网络Web服务(web service)中,交换带结构信息。SOAP为了简化网页服务器(Web Server)从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。14 RPCRPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。总结:服务提供的两大流派.传统意义以方法调用为导向通称RPC。为了企业SOA,若干厂商联合推出webservice,制定了wsdl接口定义,传输soap.当互联网时代,臃肿SOA被简化为http+xml/json.但是简化出现各种混乱。以资源为导向,任何操作无非是对资源的增删改查,于是统一的REST出现了.进化的顺序: RPC -& SOAP -& RESTful15 CGI和WSGICGI是通用网关接口,是连接web服务器和应用程序的接口,用户通过CGI来获取动态数据或文件等。CGI程序是一个独立的程序,它可以用几乎所有语言来写,包括perl,c,lua,python等等。WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务器之间的一种接口,WSGI的其中一个目的就是让用户可以用统一的语言(Python)编写前后端。官方说明:16 中间人攻击在GFW里屡见不鲜的,呵呵.中间人攻击(Man-in-the-middle attack,通常缩写为MITM)是指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。17 c10k问题所谓c10k问题,指的是服务器同时支持成千上万个客户端的问题,也就是concurrent 10 000 connection(这也是c10k这个名字的由来)。推荐: 18 socket推荐: Socket=Ip address+ TCP/UDP + port19 浏览器缓存推荐: 304 Not Modified20 HTTP1.0和HTTP1.1推荐: 请求头Host字段,一个服务器多个网站长链接文件断点续传身份认证,状态管理,Cache缓存21 AjaxAJAX,Asynchronous JavaScript and XML(异步的 JavaScript 和 XML), 是与在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。*NIXunix进程间通信方式(IPC)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。数据结构1 红黑树红黑树与AVL的比较:AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;红黑是用非严格的平衡来换取增删节点时候旋转次数的降低;所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB。编程题1 台阶问题/斐波纳挈一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。Python1fib = lambda n: n if n &= 2 else fib(n - 1) + fib(n - 2)第二种记忆方法Python1234567891011121314def memo(func):
cache = {}
def wrap(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrap@ memodef fib(i):
return fib(i-1) + fib(i-2)第三种方法Python12345def fib(n):
a, b = 0, 1
for _ in xrange(n):
a, b = b, a + b
return b2 变态台阶问题一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。Python1fib = lambda n: n if n & 2 else 2 * fib(n - 1)3 矩形覆盖我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?第2*n个矩形的覆盖方法等于第2*(n-1)加上第2*(n-2)的方法。Python1f = lambda n: 1 if n & 2 else f(n - 1) + f(n - 2)4 杨氏矩阵查找在一个m行n列二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。5 去除列表中的重复元素用集合Python1list(set(l))用字典Python123l1 = ['b','c','d','b','c','a','a']l2 = {}.fromkeys(l1).keys()print l2用字典并保持顺序Python1234l1 = ['b','c','d','b','c','a','a']l2 = list(set(l1))l2.sort(key=l1.index)print l2列表推导式Python123l1 = ['b','c','d','b','c','a','a']l2 = [][l2.append(i) for i in l1 if not i in l2]面试官提到的,先排序然后删除.6 链表成对调换1-&2-&3-&4转换成2-&1-&4-&3.Python123456789101112131415class ListNode:
def __init__(self, x):
self.val = x
self.next = Noneclass Solution:
# @param a ListNode
# @return a ListNode
def swapPairs(self, head):
if head != None and head.next != None:
next = head.next
head.next = self.swapPairs(next.next)
next.next = head
return next
return head7 创建字典的方法1 直接创建Python1dict = {'name':'earth', 'port':'80'}2 工厂方法Python123items=[('name','earth'),('port','80')]dict2=dict(items)dict1=dict((['name','earth'],['port','80']))3 fromkeys()方法Python1234dict1={}.fromkeys(('x','y'),-1)dict={'x':-1,'y':-1}dict2={}.fromkeys(('x','y'))dict2={'x':None, 'y':None}8 合并两个有序列表知乎远程面试要求编程尾递归Python12345678910111213141516def _recursion_merge_sort2(l1, l2, tmp):
if len(l1) == 0 or len(l2) == 0:
tmp.extend(l1)
tmp.extend(l2)
return tmp
if l1[0] & l2[0]:
tmp.append(l1[0])
tmp.append(l2[0])
return _recursion_merge_sort2(l1, l2, tmp)def recursion_merge_sort2(l1, l2):
return _recursion_merge_sort2(l1, l2, [])循环算法Python123456789101112def loop_merge_sort(l1, l2):
while len(l1) & 0 and len(l2) & 0:
if l1[0] & l2[0]:
tmp.append(l1[0])
tmp.append(l2[0])
tmp.extend(l1)
tmp.extend(l2)
return tmp9 交叉链表求交点去哪儿的面试,没做出来.Python1234567891011121314151617181920212223242526class ListNode:
def __init__(self, x):
self.val = x
self.next = Nonedef node(l1, l2):
length1, lenth2 = 0, 0
# 求两个链表长度
while l1.next:
l1 = l1.next
length1 += 1
while l2.next:
l2 = l2.next
length2 += 1
# 长的链表先走
if length1 & lenth2:
for _ in range(length1 - length2):
l1 = l1.next
for _ in range(length2 - length1):
l2 = l2.next
while l1 and l2:
if l1.next == l2.next:
return l1.next
l1 = l1.next
l2 = l2.next10 二分查找Python12345678910111213141516171819def binarySearch(l, t):
low, high = 0, len(l) - 1
while low & high:
print low, high
mid = (low + high) / 2
if l[mid] & t:
high = mid
elif l[mid] & t:
low = mid + 1
return mid
return low if l[low] == t else Falseif __name__ == '__main__':
l = [1, 4, 12, 45, 66, 99, 120, 444]
print binarySearch(l, 12)
print binarySearch(l, 1)
print binarySearch(l, 13)
print binarySearch(l, 444)11 快排Python123456789101112def qsort(seq):
if seq==[]:
pivot=seq[0]
lesser=qsort([x for x in seq[1:] if x&pivot])
greater=qsort([x for x in seq[1:] if x&=pivot])
return lesser+[pivot]+greaterif __name__=='__main__':
seq=[5,6,78,9,0,-1,2,3,-65,12]
print(qsort(seq))12 找零问题Python1234567891011121314151617181920def
coinChange(values, money, coinsUsed):
T[1:n]数组
#valuesCounts
钱币对应的种类数
找出来的总钱数
#coinsUsed
对应于目前钱币总数i所使用的硬币数目
for cents in range(1, money+1):
minCoins = cents
#从第一个开始到money的所有情况初始
for value in values:
if value &= cents:
temp = coinsUsed[cents - value] + 1
if temp & minCoins:
minCoins = temp
coinsUsed[cents] = minCoins
print('面值为:{0} 的最小硬币数目为:{1} '.format(cents, coinsUsed[cents]) )if __name__ == '__main__':
values = [ 25, 21, 10, 5, 1]
money = 63
coinsUsed = {i:0 for i in range(money+1)}
coinChange(values, money, coinsUsed)13 广度遍历和深度遍历二叉树给定一个数组,构建二叉树,并且按层次打印这个二叉树Python123456789101112131415161718192021222324252627282930## 14 二叉树节点class Node(object):
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = righttree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node(2, Node(5), Node(4)))## 15 层次遍历def lookup(root):
stack = [root]
while stack:
current = stack.pop(0)
print current.data
if current.left:
stack.append(current.left)
if current.right:
stack.append(current.right)## 16 深度遍历def deep(root):
if not root:
print root.data
deep(root.left)
deep(root.right)if __name__ == '__main__':
lookup(tree)
deep(tree)17 前中后序遍历深度遍历改变顺序就OK了18 求最大树深Python1234def maxDepth(root):
if not root:
return max(maxDepth(root.left), maxDepth(root.right)) + 119 求两棵树是否相同Python1234567def isSameTree(p, q):
if p == None and q == None:
return True
elif p and q :
return p.val == q.val and isSameTree(p.left,q.left) and isSameTree(p.right,q.right)
return False20 前序中序求后序推荐: Python123456789101112131415def rebuild(pre, center):
if not pre:
cur = Node(pre[0])
index = center.index(pre[0])
cur.left = rebuild(pre[1:index + 1], center[:index])
cur.right = rebuild(pre[index + 1:], center[index + 1:])
return curdef deep(root):
if not root:
deep(root.left)
deep(root.right)
print root.data21 单链表逆置Python12345678910111213141516171819202122class Node(object):
def __init__(self, data=None, next=None):
self.data = data
self.next = nextlink = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))def rev(link):
pre = link
cur = link.next
pre.next = None
while cur:
tmp = cur.next
cur.next = pre
return preroot = rev(link)while root:
print root.data
root = root.next0添加评论分享收藏}

我要回帖

更多关于 python有趣代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信