您的位置:首页 > 编程语言 > Python开发

Python朝花夕拾

2015-08-20 09:40 447 查看

Q1:HTTPError403:Forbidden

python中经常使用urllib2.urlopen函数提取网页源码,但是有些时候这个函数返回的却是:HTTPError403:Forbidden,这表明源网站不允许爬虫进行爬取

解决方法:伪装成浏览器进行访问

#!/usr/bin/envpython
#-*-coding:utf-8-*-
importurllib2
url="http://www.google.com/translate_a/t?client=t&sl=zh-CN&tl=en&q=%E7%94%B7%E5%AD%A9"
#浏览器头
headers={'User-Agent':'Mozilla/5.0(Windows;U;WindowsNT6.1;en-US;rv:1.9.1.6)Gecko/20091201Firefox/3.5.6'}
req=urllib2.Request(url=url,headers=headers)
data=urllib2.urlopen(req).read()
printdata

这样就可以得到网页源码了~

注:如果源码中中文为乱码,可以使用:

printdata.decode("UTF-8")

参见http://www.geekcome.com/content-10-3101-1.html

Q2:文件读写

read()每次读取整个文件,它通常用于将文件内容放到一个字符串变量中,readline()和readlines()之间的差异是后者一次读取整个文件,像read()一样。readlines()自动将文件内容分析成一个行的列表,该列表可以由Python的for...in...结构进行处理。另一方面,readline()每次只读取一行,通常比readlines()慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用.readline()

注意:f.readline()完成后最后一个字符是‘\n’,此时光标已经定位到了下一行的第0个位置,如果需要去除最后的回车键‘\n’,则为

line=f.readline()
line=line[:-1]

也可以用"string".strip('\n')

参见http://www.cnblogs.com/kaituorensheng/archive/2012/06/05/2537347.html

forlineinopen('poem.txt'):
printline
f=open('test.txt','r')
#以读方式打开文件
forlineinf.readlines():
  printline

逐行读取文件内容的三种方法

方法一:

f=open("foo.txt")#返回一个文件对象
line=f.readline()#调用文件的readline()方法
whileline:
printline,#后面跟','将忽略换行符
#print(line,end='')   #在Python3中使用
line=f.readline()
f.close()

方法二:
代码如下:
forlineinopen("foo.txt"):
printline,方法三:
代码如下:
f=open("c:\\1.txt","r")
lines=f.readlines()#读取全部内容
forlineinlines
printline

>>>>welcome_str="Welcomeyou"
>>>>welcome_str[0]
'W'
>>>git_list=["qiwsir","github","io"]
>>>git_list[0]
'qiwsir'

Q3:list和str转化

list和str的最大区别是:list是原处可以改变的,str则原处不可变

list和str转化

str.split()

“”.join(list)

>>>line="Hello.Iamqiwsir.Welcomeyou."
>>>line.split(".")
#以英文的句点为分隔符,得到list['Hello','Iamqiwsir','Welcomeyou','']
>>>line.split(".",1)
#这个1,就是表达了上文中的:Ifmaxsplitisgiven,atmostmaxsplitsplitsaredone.['Hello','Iamqiwsir.Welcomeyou.']
>>>name="AlbertAinstain"
#也有可能用空格来做为分隔符
>>>name.split("")['Albert','Ainstain']join可以说是split的逆运算

从list得到的字符串做切片操作

list[0][1:]#removethefirstcharacter

Q4:list对应元素相加

使用zip函数

zip就是把2个数组糅在一起
x=[1,2,3,4,5]
y=[6,7,8,9,10]
zip(x,y)就得到了
[(1,6),(2,7),(3,8),(4,9),(5,10)]

list12=[x+yforx,yinzip(list1,list2)]

求l1=[[1,2],[3,4],[5,6]]对应元素的和

>>>l1=[[1,2],[3,4],[5,6]]
>>>list(map(sum,zip(*l1)))
[9,12]

zip参考:http://www.lfyzjck.com/python-zip/

对于将两个等长的列表合并成字典:dict(zip(list1,list2))

Q5:判断数据类型

importtypes
type(x)istypes.IntType#判断是否int类型
type(x)istypes.StringType#是否string类型types.ListType==type(text)

Q6:三目运算符

true_partifconditionelsefalse_part

>>>1ifTrueelse0
1
>>>1ifFalseelse0
0

Q7:list去重

http://www.jb51.net/article/55342.htm

ids=[1,4,3,3,4,2,3,4,5,6,1]
news_ids=list(set(ids))
news_ids.sort(ids.index)

Q8:Python的函数指针

#Icmp----GeneratessomeICMPtraffic
defmatchIcmp(json_data):
  ifjson_data['network']['icmp']:
    print'GeneratessomeICMPtraffic'
func_sets=[matchEntropy,matchIcmp,matchIrc,matchHttp,matchSmtp,matchDomain,matchFile,matchRegister,matchMutex,matchApi]
forfuncinfunc_sets:
  func(json_data)
#模块中,类外的函数指针调用
defhwFunc1(x):
  print("waleking'sfunc1")
defhwFunc2(x):
  print("%s"%(x+1))
  print("waleking'sfunc2")
funcSets={"func1":hwFunc1,"func2":hwFunc2}
funcSets["func1"](1)


Q9:TypeError:‘NoneType’objectisnotiterable

原因:最终所被调用的函数所返回的值,和返回值赋值给的变量,不匹配。

Q10:Python按照书写顺序输出字典中的元素

使用
dict
时,Key是无序的。在对
dict
做迭代时,我们无法确定Key的顺序。

如果要保持Key的顺序,可以用
OrderedDict


>>>fromcollectionsimportOrderedDict
>>>d=dict([('a',1),('b',2),('c',3)])
>>>d#dict的Key是无序的
{'a':1,'c':3,'b':2}
>>>od=OrderedDict([('a',1),('b',2),('c',3)])
>>>od#OrderedDict的Key是有序的
OrderedDict([('a',1),('b',2),('c',3)])

注意,
OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序:

>>>od=OrderedDict()
>>>od['z']=1
>>>od['y']=2
>>>od['x']=3
>>>od.keys()#按照插入的Key的顺序返回
['z','y','x']

reference:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001411031239400f7181f65f33a4623bc42276a605debf6000

Q11:json相关

load(s):文件——>字典

REPORT_PATH="/tmp/report.json"
method1:result1=json.load(open(REPORT_PATH))

method2:result2=json.loads(open(REPORT_PATH).read())
dump:字典——>文件
REPORT_PATH="/tmp/report.json"
results={“123”:345,“中文”:”内容”}
json.dump(results,report,ensure_ascii=False,sort_keys=False,indent=4,encoding=”utf-8”)
dumps:字典——>字符串
json.dumps(results,ensure_ascii=False,indent=4,encoding=”utf-8”))
注:涉及到中文的dump(s)务必加上ensure_ascii=False参数,否则会出现乱码问题

Q12:ERROR:Missingdependency:Nomodulenamedxxx

python将一个文件夹作为package对待,那么这个文件夹中必须包含一个名为
__init__.py
的文件,即使它是空的。即import文件夹名

如果sys.path.append()添加路径,则导入模块时会优先导入pip安装的模块,在查找sys.path.append添加的模块,如果同名,可能出现明明自己在模块中已经定义了但是搜索不到。


reference:http://zengrong.net/post/2192.htm

Q13:默认参数的坑

defadd_end(L=[]): L.append('END') returnL >>>add_end() ['END'] >>>add_end() ['END','END']
[/code]
原因:Python函数在定义的时候,默认参数
L
的值就被计算出来了,即
[]
,因为默认参数
L
也是一个变量,它指向对象
[]
,每次调用该函数,如果改变了
L
的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的
[]
了。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
要修改上面的例子,我们可以用
None
这个不变对象来实现:

defadd_end(L=None): ifLisNone: L=[] L.append('END') returnL
>>>add_end()
['END']
>>>add_end()
['END']
为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
Q14:可变参数

defcalc(*numbers):
sum=0
forninnumbers:
sum=sum+n*n
returnsum
定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个
*
号。在函数内部,参数
numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:

>>>calc(1,2)
5
>>>calc()
0
如果已经有一个list或者tuple,要调用一个可变参数怎么办?Python允许你在list或tuple前面加一个
*
号,把list或tuple的元素变成可变参数传进去

>>>nums=[1,2,3]
>>>calc(*nums)
14
Q15:关键字参数

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
defperson(name,age,**kw):
print'name:',name,'age:',age,'other:',kw

函数
person
除了必选参数
name
age
外,还接受关键字参数
kw
。在调用该函数时,可以只传入必选参数:
>>>person('Michael',30)
name:Michaelage:30other:{}

也可以传入任意个数的关键字参数:
>>>person('Bob',35,city='Beijing')
name:Bobage:35other:{'city':'Beijing'}
>>>person('Adam',45,gender='M',job='Engineer')
name:Adamage:45other:{'gender':'M','job':'Engineer'}
[/code]
>>>kw={'city':'Beijing','job':'Engineer'}
>>>person('Jack',24,**kw)
name:Jackage:24other:{'city':'Beijing','job':'Engineer'}
[/code]
>>>args=(1,2,3,4)
>>>kw={'x':99}
>>>func(*args,**kw)
a=1b=2c=3args=(4,)kw={'x':99}
Q16:尾递归

普通递归:
deffact(n):
ifn==1:
return1
returnn*fact(n-1)
===>fact(5)
===>5*fact(4)
===>5*(4*fact(3))
===>5*(4*(3*fact(2)))
===>5*(4*(3*(2*fact(1))))
===>5*(4*(3*(2*1)))
===>5*(4*(3*2))
===>5*(4*6)
===>5*24
===>120
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
尾递归:尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的[code]fact(n)
函数改成尾递归方式,也会导致栈溢出。[/code]
deffact_iter(num,product=1):
ifnum==1:
returnproduct
returnfact_iter(num-1,num*product)
===>fact_iter(5,1)
===>fact_iter(4,5)
===>fact_iter(3,20)
===>fact_iter(2,60)
===>fact_iter(1,120)
===>120
Q17:logging相关

对于一个模块中,主脚本初始化logging之后,其他脚本可以通过log=logging.getLogger(__name__)来进行调用,此处有一个坑,就是需要在主脚本中设置log=logging.getLogger()而不能带有参数(默认是None),

1.logging对象其实是一个树形结构,每个创建的logging对象都是rootlogging对象的孩子结点。当使用logging模块的getLogger(name=None)函数构造logging对象的时候,如果name为None,这样会产生一个rootlogging对象。如果name中含有.,比如name='a.b.c',通过这种方式会产生3个logging对象,分别为c、b、a,c->b->a->root,root树的根结点,a为root的孩子结点,b为a的孩子结点,c为a的孩子结点,依次类推。
2.root结点是全局的,虽然这过程中涉及到多个模块,但是它们会共享一个root结点。
3.每个logging对象打LOG的时候,也会把LOG信息传递到传递到上层logging对象中,对于c->b->a->root这种情况,这个LOG其实会打4次,以c、b、a、root循序依次打一个LOG。

Q18:subprocess函数中shell问题

使用了shell=True这个参数。
这个时候,我们使用一整个字符串,而不是一个表来运行子进程。
Python将先运行一个shell,再用这个shell来解释这整个字符串。
rc=subprocess.call(["ls","-l"])
out=subprocess.call("ls-l",shell=True)
argsisrequiredforallcallsandshouldbeastring,orasequenceofprogramarguments.Providingasequenceofargumentsisgenerallypreferred,asitallowsthemoduletotakecareofanyrequiredescapingandquotingofarguments(e.g.topermitspacesinfilenames).Ifpassingasinglestring,eithershellmustbe
True
(seebelow)orelsethestringmustsimplynametheprogramtobeexecutedwithoutspecifyinganyarguments.
尽量不用带shell的函数

Q19:遍历列表统计每个单词出现的个数,返回字典,key为单词,value为对应的次数

最low的方法:

dict_api={}

forapiinapis:
ifapiindict_api:
dict_api[api]+=1
else:
dict_api[api]=1

优雅的方法:

l=['a','a','c','b','c']
dict((k,l.count(k))forkinset(l))

第三方库:

fromcollectionsimportCounter

dict(Counter(l))

Counter相关,
Counter
实际上也是
dict
的一个子类:

创建

>>>c=Counter()#创建一个空的Counter类
>>>c=Counter('gallahad')#从一个可iterable对象(list、tuple、dict、字符串等)创建
>>>c=Counter({'a':4,'b':2})#从一个字典对象创建
>>>c=Counter(a=4,b=2)#从一组键值对创建
当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。

>>>c=Counter("abcdefgab")
>>>c["a"]
2
>>>c["c"]
1
>>>c["h"]
0

计数器的更新(update和subtract)

reference:http://www.pythoner.com/205.html

字典按value排序:

sorted_api=sorted(dict_api.iteritems(),key=lambdad:d[1],reverse=True)
返回列表

字典合并:






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: